The `display_as` field in an `.entry_json` file must match the regex `^[a-z][0-9a-z]*$` now. This is needed to reduce errors during the final round while converting a potential submission to entry form. Modify `1992/buzzard.2/.entry.json` and `1993/rince/.entry.json` to change `display_as` field to use lower case. Correct `2012/omoikane/.entry.json` to correctly reflect changes made by commit2955e5d07eand commit2955e5d07e. Change `bin/cvt-submission.sh` to verify that the `display_as` matches the above regex. Changed `bin/cvt-submission.sh` VERSION from "2.2.2 2025-06-30" to "2.3.0 2025-07-02". Rebuild all tarballs, both at the entry and the year level due recent changes to `var.mk`, `1337.mk`, and `ioccc.css`. Rebuild sitemap due to the changes above. Ran `make update` to test and perform the above.
2733 lines
82 KiB
Bash
Executable File
2733 lines
82 KiB
Bash
Executable File
#!/usr/bin/env bash
|
|
#
|
|
# cvt-submission.sh - convert a submission into an entry
|
|
#
|
|
# Given a submission (that has won the IOCCC), with a `.auth.json`
|
|
# and `.info.json` and NO `.entry.json` file, we convert the
|
|
# `.auth.json` and `.info.json` into a new `.entry.json` file.
|
|
#
|
|
# We will form, as needed, new `author/author_handle.json`
|
|
# files for new authors, and update `author/author_handle.json`
|
|
# for authors who won previously.
|
|
#
|
|
# This script was written in 2024 by:
|
|
#
|
|
# chongo (Landon Curt Noll, http://www.isthe.com/chongo/index.html) /\oo/\
|
|
#
|
|
# with useful improvements and bug fixes by:
|
|
#
|
|
# @xexyl
|
|
# https://xexyl.net Cody Boone Ferguson
|
|
# https://ioccc.xexyl.net
|
|
#
|
|
# "Because sometimes even the IOCCC Judges need some help." :-)
|
|
#
|
|
# Copyright (c) 2024-2025 by Landon Curt Noll. All Rights Reserved.
|
|
#
|
|
# Permission to use, copy, modify, and distribute this software and
|
|
# its documentation for any purpose and without fee is hereby granted,
|
|
# provided that the above copyright, this permission notice and text
|
|
# this comment, and the disclaimer below appear in all of the following:
|
|
#
|
|
# supporting documentation
|
|
# source copies
|
|
# source works derived from this source
|
|
# binaries derived from this source or from derived source
|
|
#
|
|
# LANDON CURT NOLL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
|
|
# INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO
|
|
# EVENT SHALL LANDON CURT NOLL BE LIABLE FOR ANY SPECIAL, INDIRECT OR
|
|
# CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF
|
|
# USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
|
|
# OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
|
|
# PERFORMANCE OF THIS SOFTWARE.
|
|
#
|
|
# chongo (Landon Curt Noll, http://www.isthe.com/chongo/index.html) /\oo/\
|
|
#
|
|
# Share and enjoy! :-)
|
|
|
|
|
|
# firewall - run only with a bash that is version 5.1.8 or later
|
|
#
|
|
# The "/usr/bin/env bash" command must result in using a bash that
|
|
# is version 5.1.8 or later.
|
|
#
|
|
# We could relax this version and insist on version 4.2 or later. Versions
|
|
# of bash between 4.2 and 5.1.7 might work. However, to be safe, we will require
|
|
# bash version 5.1.8 or later.
|
|
#
|
|
# WHY 5.1.8 and not 4.2? This safely is done because macOS Homebrew bash we
|
|
# often use is "version 5.2.26(1)-release" or later, and the RHEL Linux bash we
|
|
# use often use is "version 5.1.8(1)-release" or later. These versions are what
|
|
# we initially tested. We recommend you either upgrade bash or install a newer
|
|
# version of bash and adjust your $PATH so that "/usr/bin/env bash" finds a bash
|
|
# that is version 5.1.8 or later.
|
|
#
|
|
# NOTE: The macOS shipped, as of 2024 March 15, a version of bash is something like
|
|
# bash "version 3.2.57(1)-release". That macOS shipped version of bash
|
|
# will NOT work. For users of macOS we recommend you install Homebrew,
|
|
# (see https://brew.sh), and then run "brew install bash" which will
|
|
# typically install it into /opt/homebrew/bin/bash, and then arrange your $PATH
|
|
# so that "/usr/bin/env bash" finds "/opt/homebrew/bin" (or whatever the
|
|
# Homebrew bash is).
|
|
#
|
|
# NOTE: And while MacPorts might work, we noticed a number of subtle differences
|
|
# with some of their ported tools to suggest you might be better off
|
|
# with installing Homebrew (see https://brew.sh). No disrespect is intended
|
|
# to the MacPorts team as they do a commendable job. Nevertheless we ran
|
|
# into enough differences with MacPorts environments to suggest you
|
|
# might find a better experience with this tool under Homebrew instead.
|
|
#
|
|
if [[ -z ${BASH_VERSINFO[0]} ||
|
|
${BASH_VERSINFO[0]} -lt 5 ||
|
|
${BASH_VERSINFO[0]} -eq 5 && ${BASH_VERSINFO[1]} -lt 1 ||
|
|
${BASH_VERSINFO[0]} -eq 5 && ${BASH_VERSINFO[1]} -eq 1 && ${BASH_VERSINFO[2]} -lt 8 ]]; then
|
|
echo "$0: ERROR: bash version needs to be >= 5.1.8: $BASH_VERSION" 1>&2
|
|
echo "$0: Warning: bash version >= 4.2 might work but 5.1.8 was the minimum we tested" 1>&2
|
|
echo "$0: Notice: For macOS users: install Homebrew (see https://brew.sh), then run" \
|
|
""brew install bash" and then modify your \$PATH so that \"#!/usr/bin/env bash\"" \
|
|
"finds the Homebrew installed (usually /opt/homebrew/bin/bash) version of bash" 1>&2
|
|
exit 4
|
|
fi
|
|
|
|
|
|
# setup bash file matching
|
|
#
|
|
# We must declare arrays with -ag or -Ag, and we need loops to "export" modified variables.
|
|
# This requires a bash with a version 4.2 or later. See the larger comment above about bash versions.
|
|
#
|
|
shopt -s nullglob # enable expanded to nothing rather than remaining unexpanded
|
|
shopt -u failglob # disable error message if no matches are found
|
|
shopt -u dotglob # disable matching files starting with .
|
|
shopt -u nocaseglob # disable strict case matching
|
|
shopt -u extglob # enable extended globbing patterns
|
|
shopt -s globstar # enable ** to match all files and zero or more directories and subdirectories
|
|
|
|
|
|
# IOCCC requires use of C locale
|
|
#
|
|
export LANG="C"
|
|
export LC_CTYPE="C"
|
|
export LC_NUMERIC="C"
|
|
export LC_TIME="C"
|
|
export LC_COLLATE="C"
|
|
export LC_MONETARY="C"
|
|
export LC_MESSAGES="C"
|
|
export LC_PAPER="C"
|
|
export LC_NAME="C"
|
|
export LC_ADDRESS="C"
|
|
export LC_TELEPHONE="C"
|
|
export LC_MEASUREMENT="C"
|
|
export LC_IDENTIFICATION="C"
|
|
export LC_ALL="C"
|
|
|
|
|
|
# set variables referenced in the usage message
|
|
#
|
|
export VERSION="2.3.0 2025-07-02"
|
|
NAME=$(basename "$0")
|
|
export NAME
|
|
export V_FLAG=0
|
|
GIT_TOOL=$(type -P git)
|
|
export GIT_TOOL
|
|
if [[ -z "$GIT_TOOL" ]]; then
|
|
echo "$0: FATAL: git tool is not installed or not in \$PATH" 1>&2
|
|
exit 5
|
|
fi
|
|
"$GIT_TOOL" rev-parse --is-inside-work-tree >/dev/null 2>&1
|
|
status="$?"
|
|
if [[ $status -eq 0 ]]; then
|
|
TOPDIR=$("$GIT_TOOL" rev-parse --show-toplevel)
|
|
fi
|
|
export TOPDIR
|
|
#
|
|
VERGE=$(type -P verge)
|
|
export VERGE
|
|
if [[ -z $VERGE ]]; then
|
|
echo "$0: FATAL: verge is not installed or not in \$PATH" 1>&2
|
|
echo "$0: notice: to install verge:" 1>&2
|
|
echo "$0: notice: run: git clone https://github.com/ioccc-src/mkiocccentry.git" 1>&2
|
|
echo "$0: notice: then: cd mkiocccentry && make clobber all" 1>&2
|
|
echo "$0: notice: then: cd jparse && sudo make install clobber" 1>&2
|
|
exit 5
|
|
fi
|
|
#
|
|
JSTRDECODE=$(type -P jstrdecode)
|
|
export JSTRDECODE
|
|
if [[ -z $JSTRDECODE ]]; then
|
|
echo "$0: FATAL: jstrdecode is not installed or not in \$PATH" 1>&2
|
|
echo "$0: notice: to install jstrdecode:" 1>&2
|
|
echo "$0: notice: run: git clone https://github.com/ioccc-src/mkiocccentry.git" 1>&2
|
|
echo "$0: notice: then: cd mkiocccentry && make clobber all" 1>&2
|
|
echo "$0: notice: then: cd jparse && sudo make install clobber" 1>&2
|
|
exit 5
|
|
fi
|
|
export MIN_JSTRDECODE_VERSION="2.1.2"
|
|
JSTRDECODE_VERSION=$("$JSTRDECODE" -V | head -1 | awk '{print $3;}')
|
|
if ! "$VERGE" "$JSTRDECODE_VERSION" "$MIN_JSTRDECODE_VERSION"; then
|
|
echo "$0: FATAL: jstrdecode version: $JSTRDECODE_VERSION < minimum version: $MIN_JSTRDECODE_VERSION" 1>&2
|
|
echo "$0: notice: consider updating jstrdecode from mkiocccentry repo" 1>&2
|
|
echo "$0: notice: run: git clone https://github.com/ioccc-src/mkiocccentry.git" 1>&2
|
|
echo "$0: notice: then: cd mkiocccentry && make clobber all" 1>&2
|
|
echo "$0: notice: then: cd jparse && sudo make install clobber" 1>&2
|
|
exit 5
|
|
fi
|
|
#
|
|
CHKENTRY_TOOL=$(type -P chkentry)
|
|
export CHKENTRY_TOOL
|
|
if [[ -z "$CHKENTRY_TOOL" ]]; then
|
|
echo "$0: FATAL: chkentry tool is not installed or not in \$PATH" 1>&2
|
|
echo "$0: Notice: if needed: $GIT_TOOL clone $MKIOCCCENTRY_REPO; cd mkiocccentry" 1>&2
|
|
echo "$0: Notice: then if needed: make clobber all install" 1>&2
|
|
exit 5
|
|
fi
|
|
export MIN_CHKENTRY_VERSION="2.0.5"
|
|
CHKENTRY_VERSION=$("$CHKENTRY_TOOL" -V | head -1 | awk '{print $3;}')
|
|
if ! "$VERGE" "$CHKENTRY_VERSION" "$MIN_CHKENTRY_VERSION"; then
|
|
echo "$0: FATAL: chkentry version: $CHKENTRY_VERSION < minimum version: $MIN_CHKENTRY_VERSION" 1>&2
|
|
echo "$0: notice: consider updating chkentry from mkiocccentry repo" 1>&2
|
|
echo "$0: notice: run: git clone https://github.com/ioccc-src/mkiocccentry.git" 1>&2
|
|
echo "$0: notice: then: cd mkiocccentry && make clobber all" 1>&2
|
|
echo "$0: notice: then: cd jparse && sudo make install clobber" 1>&2
|
|
exit 5
|
|
fi
|
|
export GEN_README_TOOL="$TOPDIR/bin/gen-readme.sh"
|
|
#
|
|
GTAR_TOOL=$(type -P gtar)
|
|
export GTAR_TOOL
|
|
if [[ -z "$GIT_TOOL" ]]; then
|
|
echo "$0: FATAL: gtar (gnu tar) tool is not installed or not in \$PATH" 1>&2
|
|
exit 5
|
|
fi
|
|
#
|
|
export REPO_TOP_URL="https://github.com/ioccc-src/winner"
|
|
# GitHub puts individual files under the "blob/master" sub-directory.
|
|
export REPO_URL="$REPO_TOP_URL/blob/master"
|
|
JPARSE_TOOL=$(type -P jparse)
|
|
export JPARSE_TOOL
|
|
if [[ -z "$JPARSE_TOOL" ]]; then
|
|
echo "$0: FATAL: jparse tool is not installed or not in \$PATH" 1>&2
|
|
echo "$0: notice: to install jparse:" 1>&2
|
|
echo "$0: notice: run: git clone https://github.com/ioccc-src/mkiocccentry.git" 1>&2
|
|
echo "$0: notice: then: cd mkiocccentry && make clobber all" 1>&2
|
|
echo "$0: notice: then: cd jparse && sudo make install clobber" 1>&2
|
|
exit 5
|
|
fi
|
|
export MKIOCCCENTRY_REPO="https://github.com/ioccc-src/mkiocccentry"
|
|
export INPUT_DATA_FILE
|
|
#
|
|
export NO_COMMENT="mandatory comment: because comments were removed from the original JSON spec"
|
|
export ENTRY_JSON_FORMAT_VERSION="1.2 2024-09-25"
|
|
export AUTHOR_JSON_FORMAT_VERSION="1.1 2024-02-11"
|
|
#
|
|
export NOOP=
|
|
export DO_NOT_PROCESS=
|
|
#
|
|
export TARBALL_DIR="/var/tmp"
|
|
#
|
|
export X_3="X""X""X"
|
|
|
|
|
|
# usage
|
|
#
|
|
export USAGE="usage: $0 [-h] [-v level] [-V] [-d topdir]
|
|
[-c chkentry] [-g gen-readme.sh] [-T tarball_dir]
|
|
[-i input_data] [-n] [-N] YYYY/dir
|
|
|
|
-h print help message and exit
|
|
-v level set verbosity level (def level: 0)
|
|
-V print version string and exit
|
|
|
|
-d topdir set topdir (def: $TOPDIR)
|
|
-c chkentry path to the chkentry tool (def: $CHKENTRY_TOOL)
|
|
-g gen-readme.sh path to the gen-readme.sh tool (def: $GEN_README_TOOL)
|
|
|
|
-T tarball_dir where to form the compressed tarball of modified files (def: $TARBALL_DIR)
|
|
|
|
-i input_data read data from file and disable asking if correct (def: from stdin)
|
|
|
|
-n go thru the actions, but do not update any files (def: do the action)
|
|
-N do not process anything, just parse arguments (def: process something)
|
|
|
|
YYYY/dir path from topdir to entry directory
|
|
|
|
Exit codes:
|
|
0 all OK
|
|
1 invalid user input
|
|
2 -h and help string printed or -V and version string printed
|
|
3 command line error
|
|
4 bash version is too old
|
|
5 some internal tool is not found or not an executable file
|
|
6 problems found with or in the topdir or topdir/YYYY directory
|
|
7 invalid or missing .info.json and/or .auth.json files
|
|
>= 10 internal error
|
|
|
|
$NAME version: $VERSION"
|
|
|
|
|
|
# prompt_string
|
|
#
|
|
# Prompt the user for a string and output as a decoded JSON string.
|
|
#
|
|
# If "-i input_data: is used, the printing of the prompt is disabled,
|
|
# and the query of correctness is also disabled.
|
|
#
|
|
# usage:
|
|
# prompt_string item_name
|
|
#
|
|
# returns:
|
|
# 0 ==> no errors detected
|
|
# > 0 ==> function error number
|
|
#
|
|
function prompt_string
|
|
{
|
|
local INPUT; # user input
|
|
local DECODED; # INPUT decoded as JSON string
|
|
local Y_OR_N; # y or n
|
|
local ITEM_NAME; # name of the item being prompted for
|
|
|
|
# parse args
|
|
#
|
|
if [[ $# -ne 1 ]]; then
|
|
echo "$0: ERROR: in prompt_string: expected 1 arg, found $#" 1>&2
|
|
return 1
|
|
fi
|
|
ITEM_NAME="$1"
|
|
if [[ -z $ITEM_NAME ]]; then
|
|
echo "$0: ERROR: in prompt_string: 1st arg is empty" 1>&2
|
|
return 2
|
|
fi
|
|
|
|
# obtain the string
|
|
#
|
|
while :; do
|
|
|
|
# prompt for value
|
|
#
|
|
if [[ -z $INPUT_DATA_FILE ]]; then
|
|
echo -n "Enter $ITEM_NAME: "
|
|
fi
|
|
read -r INPUT
|
|
if [[ -z "$INPUT" ]]; then
|
|
echo "$0: Warning: in prompt_string: $ITEM_NAME cannot be empty, try again" 1>&2
|
|
echo 1>&2
|
|
continue
|
|
fi
|
|
|
|
# JSON decode value
|
|
#
|
|
DECODED=$("$JSTRDECODE" -d -q -N -- "$INPUT")
|
|
status="$?"
|
|
if [[ $status -ne 0 || -z $DECODED ]]; then
|
|
echo "$0: ERROR: in prompt_string: $JSTRDECODE -d -q -N -- $INPUT failed," \
|
|
"error code: $status" 1>&2
|
|
exit 1
|
|
fi
|
|
|
|
# verify JSON decoded value
|
|
#
|
|
if [[ -z $INPUT_DATA_FILE ]]; then
|
|
echo
|
|
echo "Verify decoded $ITEM_NAME: $DECODED" 1>&2
|
|
echo
|
|
echo -n 'Is that correct? [Y,n]: '
|
|
read -r Y_OR_N
|
|
if [[ -z $Y_OR_N || $Y_OR_N == y || $Y_OR_N == Y || $Y_OR_N == yes || $Y_OR_N == YES || $Y_OR_N == Yes ]]; then
|
|
break
|
|
fi
|
|
echo
|
|
else
|
|
break
|
|
fi
|
|
done
|
|
if [[ -z $INPUT_DATA_FILE ]]; then
|
|
echo
|
|
fi
|
|
|
|
# set VALUE to the JSON decoded string
|
|
#
|
|
VALUE="$DECODED"
|
|
return 0
|
|
}
|
|
|
|
|
|
# prompt_word
|
|
#
|
|
# Prompt the user for a lower case word and output as a decoded JSON word.
|
|
#
|
|
# The input must start work a lower case letter followed by 0 or more
|
|
# local case letters or digits:
|
|
#
|
|
# ^[a-z][0-9a-z]*$
|
|
#
|
|
# If "-i input_data: is used, the printing of the prompt is disabled,
|
|
# and the query of correctness is also disabled.
|
|
#
|
|
# usage:
|
|
# prompt_word item_name
|
|
#
|
|
# returns:
|
|
# 0 ==> no errors detected
|
|
# > 0 ==> function error number
|
|
#
|
|
function prompt_word
|
|
{
|
|
local INPUT; # user input
|
|
local DECODED; # INPUT decoded as JSON string
|
|
local Y_OR_N; # y or n
|
|
local ITEM_NAME; # name of the item being prompted for
|
|
|
|
# parse args
|
|
#
|
|
if [[ $# -ne 1 ]]; then
|
|
echo "$0: ERROR: in prompt_word: expected 1 arg, found $#" 1>&2
|
|
return 1
|
|
fi
|
|
ITEM_NAME="$1"
|
|
if [[ -z $ITEM_NAME ]]; then
|
|
echo "$0: ERROR: in prompt_word: 1st arg is empty" 1>&2
|
|
return 2
|
|
fi
|
|
|
|
# obtain the lower case word
|
|
#
|
|
while :; do
|
|
|
|
# prompt for value
|
|
#
|
|
if [[ -z $INPUT_DATA_FILE ]]; then
|
|
echo -n "Enter $ITEM_NAME: "
|
|
fi
|
|
read -r INPUT
|
|
if [[ -z "$INPUT" ]]; then
|
|
echo "$0: Warning: in prompt_word: $ITEM_NAME cannot be empty, try again" 1>&2
|
|
echo 1>&2
|
|
continue
|
|
fi
|
|
|
|
# must start with lower case lewtter and followed bu 0 or more lower case letters and digits
|
|
#
|
|
if ! [[ $INPUT =~ ^[a-z][0-9a-z]*$ ]]; then
|
|
echo "$0: Warning: in prompt_word: $ITEM_NAME must match "'^[a-z][0-9a-z]*$'" regex, try again" 1>&2
|
|
echo 1>&2
|
|
continue
|
|
fi
|
|
|
|
# JSON decode value
|
|
#
|
|
DECODED=$("$JSTRDECODE" -d -q -N -- "$INPUT")
|
|
status="$?"
|
|
if [[ $status -ne 0 || -z $DECODED ]]; then
|
|
echo "$0: ERROR: in prompt_word: $JSTRDECODE -d -q -N -- $INPUT failed," \
|
|
"error code: $status" 1>&2
|
|
exit 1
|
|
fi
|
|
|
|
# verify JSON decoded value
|
|
#
|
|
if [[ -z $INPUT_DATA_FILE ]]; then
|
|
echo
|
|
echo "Verify decoded $ITEM_NAME: $DECODED" 1>&2
|
|
echo
|
|
echo -n 'Is that correct? [Y,n]: '
|
|
read -r Y_OR_N
|
|
if [[ -z $Y_OR_N || $Y_OR_N == y || $Y_OR_N == Y || $Y_OR_N == yes || $Y_OR_N == YES || $Y_OR_N == Yes ]]; then
|
|
break
|
|
fi
|
|
echo
|
|
else
|
|
break
|
|
fi
|
|
done
|
|
if [[ -z $INPUT_DATA_FILE ]]; then
|
|
echo
|
|
fi
|
|
|
|
# set VALUE to the JSON decoded string
|
|
#
|
|
VALUE="$DECODED"
|
|
return 0
|
|
}
|
|
|
|
|
|
# prompt_integer
|
|
#
|
|
# Prompt the user for an integer and output as a decoded JSON string.
|
|
#
|
|
# If "-i input_data: is used, the printing of the prompt is disabled,
|
|
# and the query of correctness is also disabled.
|
|
#
|
|
# usage:
|
|
# prompt_integer item_name
|
|
#
|
|
# returns:
|
|
# 0 ==> no errors detected
|
|
# > 0 ==> function error number
|
|
#
|
|
function prompt_integer
|
|
{
|
|
local INPUT; # user input
|
|
local DECODED; # INPUT decoded as JSON string
|
|
local Y_OR_N; # y or n
|
|
local ITEM_NAME; # name of the item being prompted for
|
|
|
|
# parse args
|
|
#
|
|
if [[ $# -ne 1 ]]; then
|
|
echo "$0: ERROR: in prompt_integer: expected 1 arg, found $#" 1>&2
|
|
return 1
|
|
fi
|
|
ITEM_NAME="$1"
|
|
if [[ -z $ITEM_NAME ]]; then
|
|
echo "$0: ERROR: in prompt_integer: 1st arg is empty" 1>&2
|
|
return 2
|
|
fi
|
|
|
|
# obtain the integer
|
|
#
|
|
while :; do
|
|
|
|
# prompt for value
|
|
#
|
|
if [[ -z $INPUT_DATA_FILE ]]; then
|
|
echo -n "Enter $ITEM_NAME: "
|
|
fi
|
|
read -r INPUT
|
|
if [[ -z "$INPUT" ]]; then
|
|
echo "$0: Warning: in prompt_integer: $ITEM_NAME cannot be empty, try again" 1>&2
|
|
echo 1>&2
|
|
continue
|
|
fi
|
|
if [[ $INPUT =~ ^[[:digit:]]+$ && $INPUT -ge 0 && $INPUT -le 4294967295 ]]; then
|
|
# JSON decode value
|
|
#
|
|
DECODED=$("$JSTRDECODE" -d -q -N -- "$INPUT")
|
|
status="$?"
|
|
if [[ $status -ne 0 || -z $DECODED ]]; then
|
|
echo "$0: ERROR: in prompt_integer: $JSTRDECODE -d -q -N -- $INPUT failed," \
|
|
"error code: $status" 1>&2
|
|
exit 1
|
|
fi
|
|
else
|
|
echo "$0: Warning: in prompt_integer: $ITEM_NAME must be an integer >= 0 and <= 4294967295, try again" 1>&2
|
|
echo 1>&2
|
|
continue
|
|
fi
|
|
|
|
# verify JSON decoded value
|
|
#
|
|
if [[ -z $INPUT_DATA_FILE ]]; then
|
|
echo
|
|
echo "Verify decoded $ITEM_NAME: $DECODED" 1>&2
|
|
echo
|
|
echo -n 'Is that correct? [Y,n]: '
|
|
read -r Y_OR_N
|
|
if [[ -z $Y_OR_N || $Y_OR_N == y || $Y_OR_N == Y || $Y_OR_N == yes || $Y_OR_N == YES || $Y_OR_N == Yes ]]; then
|
|
break
|
|
fi
|
|
echo
|
|
else
|
|
break
|
|
fi
|
|
done
|
|
if [[ -z $INPUT_DATA_FILE ]]; then
|
|
echo
|
|
fi
|
|
|
|
# set VALUE to the JSON decoded string
|
|
#
|
|
VALUE="$DECODED"
|
|
return 0
|
|
}
|
|
|
|
|
|
# manifest_csv
|
|
#
|
|
# Write a manifest entry in CSV form to stdout.
|
|
#
|
|
# usage:
|
|
# manifest_csv file_path inventory_order OK_to_edit display_as display_via_github entry_text
|
|
#
|
|
# file_path path to the file relative to the entry directory
|
|
# inventory_order inventory order as displayed in the entry index.html file
|
|
# OK_to_edit boolean for if file should be modified, edited, replaced, or even removed
|
|
# display_as kind of file it is and in particular how to display it
|
|
# display_via_github boolean indicates whether the file should be viewed via GitHub or not
|
|
# entry_text summary of what the file purpose is
|
|
#
|
|
# returns:
|
|
# 0 ==> no errors detected, but output may be empty
|
|
# > 0 ==> function error number
|
|
#
|
|
function manifest_csv
|
|
{
|
|
local FILE_PATH; # path to the file relative to the entry directory
|
|
local INVENTORY_ORDER; # inventory order as displayed in the entry index.html file
|
|
local OK_TO_EDIT; # boolean for if file should be modified, edited, replaced, or even removed
|
|
local DISPLAY_AS; # kind of file it is and in particular how to display it
|
|
local DISPLAY_VIA_GITHUB; # boolean indicates whether the file should be viewed via GitHub or not
|
|
local ENTRY_TEXT; # summary of what the file purpose is
|
|
|
|
# parse args
|
|
#
|
|
if [[ $# -ne 6 ]]; then
|
|
echo "$0: ERROR: in manifest_entry: expected 6 args, found $#" 1>&2
|
|
return 1
|
|
fi
|
|
FILE_PATH="${1//,/%%COMMA%%}"
|
|
if [[ -z $FILE_PATH ]]; then
|
|
echo "$0: ERROR: in manifest_entry: file_path arg 1 is empty" 1>&2
|
|
return 2
|
|
fi
|
|
INVENTORY_ORDER="${2//,/%%COMMA%%}"
|
|
if [[ -z $INVENTORY_ORDER ]]; then
|
|
echo "$0: ERROR: in manifest_entry: inventory_order arg 2 is empty" 1>&2
|
|
return 3
|
|
fi
|
|
OK_TO_EDIT="${3//,/%%COMMA%%}"
|
|
if [[ -z $OK_TO_EDIT ]]; then
|
|
echo "$0: ERROR: in manifest_entry: OK_to_edit arg 3 is empty" 1>&2
|
|
return 4
|
|
fi
|
|
DISPLAY_AS="${4//,/%%COMMA%%}"
|
|
if [[ -z $DISPLAY_AS ]]; then
|
|
echo "$0: ERROR: in manifest_entry: display_as arg 4 is empty" 1>&2
|
|
return 5
|
|
fi
|
|
DISPLAY_VIA_GITHUB="${5//,/%%COMMA%%}"
|
|
if [[ -z $DISPLAY_VIA_GITHUB ]]; then
|
|
echo "$0: ERROR: in manifest_entry: display_via_github arg 5 is empty" 1>&2
|
|
return 6
|
|
fi
|
|
ENTRY_TEXT="${6//,/%%COMMA%%}"
|
|
if [[ -z $ENTRY_TEXT ]]; then
|
|
echo "$0: ERROR: in manifest_entry: entry_text arg 6 is empty" 1>&2
|
|
return 7
|
|
fi
|
|
|
|
# write CSV line
|
|
#
|
|
printf "%s,%s,%s,%s,%s,%s\n" "$FILE_PATH" "$INVENTORY_ORDER" "$OK_TO_EDIT" \
|
|
"$DISPLAY_AS" "$DISPLAY_VIA_GITHUB" "$ENTRY_TEXT"
|
|
|
|
return 0
|
|
}
|
|
|
|
|
|
# manifest_entry
|
|
#
|
|
# Write a manifest entry in JSON form to stdout.
|
|
#
|
|
# usage:
|
|
# manifest_entry file_path inventory_order OK_to_edit display_as display_via_github entry_text comma
|
|
#
|
|
# file_path path to the file relative to the entry directory
|
|
# inventory_order inventory order as displayed in the entry index.html file
|
|
# OK_to_edit boolean for if file should be modified, edited, replaced, or even removed
|
|
# display_as kind of file it is and in particular how to display it
|
|
# display_via_github boolean indicates whether the file should be viewed via GitHub or not
|
|
# entry_text summary of what the file purpose is
|
|
# comma "comma" ==> print comma after array element
|
|
#
|
|
# returns:
|
|
# 0 ==> no errors detected, but output may be empty
|
|
# > 0 ==> function error number
|
|
#
|
|
function manifest_entry
|
|
{
|
|
local FILE_PATH; # path to the file relative to the entry directory
|
|
local INVENTORY_ORDER; # inventory order as displayed in the entry index.html file
|
|
local OK_TO_EDIT; # boolean for if file should be modified, edited, replaced, or even removed
|
|
local DISPLAY_AS; # kind of file it is and in particular how to display it
|
|
local DISPLAY_VIA_GITHUB; # boolean indicates whether the file should be viewed via GitHub or not
|
|
local ENTRY_TEXT; # summary of what the file purpose is
|
|
local COMMA; # true ==> print comma after array element
|
|
|
|
# parse args
|
|
#
|
|
if [[ $# -ne 7 ]]; then
|
|
echo "$0: ERROR: in manifest_entry: expected 7 args, found $#" 1>&2
|
|
return 1
|
|
fi
|
|
FILE_PATH="${1///%%COMMA%%/,}"
|
|
if [[ -z $FILE_PATH ]]; then
|
|
echo "$0: ERROR: in manifest_entry: file_path arg 1 is empty" 1>&2
|
|
return 2
|
|
fi
|
|
INVENTORY_ORDER="${2///%%COMMA%%/,}"
|
|
if [[ -z $INVENTORY_ORDER ]]; then
|
|
echo "$0: ERROR: in manifest_entry: inventory_order arg 2 is empty" 1>&2
|
|
return 3
|
|
fi
|
|
OK_TO_EDIT="${3///%%COMMA%%/,}"
|
|
if [[ -z $OK_TO_EDIT ]]; then
|
|
echo "$0: ERROR: in manifest_entry: OK_to_edit arg 3 is empty" 1>&2
|
|
return 4
|
|
fi
|
|
DISPLAY_AS="${4///%%COMMA%%/,}"
|
|
if [[ -z $DISPLAY_AS ]]; then
|
|
echo "$0: ERROR: in manifest_entry: display_as arg 4 is empty" 1>&2
|
|
return 5
|
|
fi
|
|
DISPLAY_VIA_GITHUB="${5///%%COMMA%%/,}"
|
|
if [[ -z $DISPLAY_VIA_GITHUB ]]; then
|
|
echo "$0: ERROR: in manifest_entry: display_via_github arg 5 is empty" 1>&2
|
|
return 6
|
|
fi
|
|
ENTRY_TEXT="${6///%%COMMA%%/,}"
|
|
if [[ -z $ENTRY_TEXT ]]; then
|
|
echo "$0: ERROR: in manifest_entry: entry_text arg 6 is empty" 1>&2
|
|
return 7
|
|
fi
|
|
COMMA="$7"
|
|
|
|
# start of manifest entry
|
|
#
|
|
printf " {\n"
|
|
|
|
# output file_path
|
|
#
|
|
printf " \"file_path\" : \"%s\",\n" "$FILE_PATH"
|
|
|
|
# output inventory_order
|
|
#
|
|
printf " \"inventory_order\" : %s,\n" "$INVENTORY_ORDER"
|
|
|
|
# output OK_to_edit
|
|
#
|
|
printf " \"OK_to_edit\" : %s,\n" "$OK_TO_EDIT"
|
|
|
|
# output display_as
|
|
#
|
|
printf " \"display_as\" : \"%s\",\n" "$DISPLAY_AS"
|
|
|
|
# output display_via_github
|
|
#
|
|
printf " \"display_via_github\" : %s,\n" "$DISPLAY_VIA_GITHUB"
|
|
|
|
# output entry_text
|
|
#
|
|
printf " \"entry_text\" : \"%s\"\n" "$ENTRY_TEXT"
|
|
|
|
# end of manifest entry
|
|
#
|
|
# We do not issue a return, allowing either the next manifest entry or
|
|
# the end of the manifest array to close the array.
|
|
#
|
|
if [[ $COMMA == "comma" ]]; then
|
|
printf " },\n"
|
|
else
|
|
printf " }\n"
|
|
fi
|
|
return 0
|
|
}
|
|
|
|
|
|
# write_author_handle_file - update author_handle JSON file
|
|
#
|
|
# usage:
|
|
#
|
|
# write_author_handle_file AUTHOR_INFO ENTRY_ID_SET TMP_FILENAME JSON_FILENAME
|
|
#
|
|
# AUTHOR_INFO Associative array of author_handle JSON member names and values
|
|
# ENTRY_ID_SET Array of entry_id values
|
|
# TMP_FILENAME temporary JSON file to write into
|
|
# JSON_FILENAME author_handle JSON file to create or modify if needed
|
|
#
|
|
# return:
|
|
#
|
|
# 0 ==> all OK
|
|
# =! 0 ==> error
|
|
#
|
|
function write_author_handle_file
|
|
{
|
|
local -n AUTH_INFO; # name of array of author_handle JSON member names and values
|
|
local -n ENTRY_SET; # name of array of entry_id values
|
|
local TMP_FILENAME; # temporary JSON file to write into
|
|
local JSON_FILENAME; # author_handle JSON file to create or modify if needed
|
|
local entry_set_length; # length of the array of entry_id values
|
|
local final_comma; # 2nd to final index of the array of entry_id values
|
|
local i;
|
|
|
|
# parse args
|
|
#
|
|
if [[ $# -ne 4 ]]; then
|
|
echo "$0: ERROR: in write_author_handle_file: expected 4 args, found $#" 1>&2
|
|
return 1
|
|
fi
|
|
AUTH_INFO="$1"
|
|
ENTRY_SET="$2"
|
|
TMP_FILENAME="$3"
|
|
JSON_FILENAME="$4"
|
|
|
|
# write data to the temporary file
|
|
#
|
|
{
|
|
# write start of temporary author_handle JSON file
|
|
#
|
|
printf "{\n"
|
|
printf " \"no_comment\" : \"%s\",\n" "${AUTH_INFO[no_comment]}"
|
|
printf " \"author_JSON_format_version\" : \"%s\",\n" "${AUTH_INFO[author_JSON_format_version]}"
|
|
printf " \"author_handle\" : \"%s\",\n" "${AUTH_INFO[author_handle]}"
|
|
printf " \"full_name\" : \"%s\",\n" "${AUTH_INFO[name]}"
|
|
printf " \"sort_word\" : \"%s\",\n" "${AUTH_INFO[sort_word]}"
|
|
printf " \"location_code\" : \"%s\",\n" "${AUTH_INFO[location_code]}"
|
|
if [[ ${AUTH_INFO[email]} == null || -z ${AUTH_INFO[email]} ]]; then
|
|
printf " \"email\" : null,\n"
|
|
else
|
|
printf " \"email\" : \"%s\",\n" "${AUTH_INFO[email]}"
|
|
fi
|
|
if [[ ${AUTH_INFO[url]} == null || -z ${AUTH_INFO[url]} ]]; then
|
|
printf " \"url\" : null,\n"
|
|
else
|
|
printf " \"url\" : \"%s\",\n" "${AUTH_INFO[url]}"
|
|
fi
|
|
if [[ ${AUTH_INFO[alt_url]} == null || -z ${AUTH_INFO[alt_url]} ]]; then
|
|
printf " \"alt_url\" : null,\n"
|
|
else
|
|
printf " \"alt_url\" : \"%s\",\n" "${AUTH_INFO[alt_url]}"
|
|
fi
|
|
if [[ ${AUTH_INFO[deprecated_twitter_handle]} == null || -z ${AUTH_INFO[deprecated_twitter_handle]} ]]; then
|
|
printf " \"deprecated_twitter_handle\" : null,\n"
|
|
else
|
|
printf " \"deprecated_twitter_handle\" : \"%s\",\n" "${AUTH_INFO[deprecated_twitter_handle]}"
|
|
fi
|
|
if [[ ${AUTH_INFO[mastodon]} == null || -z ${AUTH_INFO[mastodon]} ]]; then
|
|
printf " \"mastodon\" : null,\n"
|
|
else
|
|
printf " \"mastodon\" : \"%s\",\n" "${AUTH_INFO[mastodon]}"
|
|
fi
|
|
if [[ ${AUTH_INFO[mastodon_url]} == null || -z ${AUTH_INFO[mastodon_url]} ]]; then
|
|
printf " \"mastodon_url\" : null,\n"
|
|
else
|
|
printf " \"mastodon_url\" : \"%s\",\n" "${AUTH_INFO[mastodon_url]}"
|
|
fi
|
|
if [[ ${AUTH_INFO[github]} == null || -z ${AUTH_INFO[github]} ]]; then
|
|
printf " \"github\" : null,\n"
|
|
else
|
|
printf " \"github\" : \"%s\",\n" "${AUTH_INFO[github]}"
|
|
fi
|
|
if [[ ${AUTH_INFO[affiliation]} == null || -z ${AUTH_INFO[affiliation]} ]]; then
|
|
printf " \"affiliation\" : null,\n"
|
|
else
|
|
printf " \"affiliation\" : \"%s\",\n" "${AUTH_INFO[affiliation]}"
|
|
fi
|
|
|
|
# write the winning_entry_set array to the temporary author_handle JSON file
|
|
#
|
|
printf " \"winning_entry_set\" : [\n"
|
|
entry_set_length=${#ENTRY_SET[@]}
|
|
case "$entry_set_length" in
|
|
0) echo "$0: ERROR: Array of entry_id values is empty";
|
|
return 1
|
|
;;
|
|
1) printf " {\n"
|
|
printf " \"entry_id\" : \"%s\"\n" "${ENTRY_SET[0]}"
|
|
printf " }\n"
|
|
;;
|
|
*) ((final_comma=entry_set_length-2))
|
|
((final=entry_set_length-1))
|
|
for j in $(seq 0 "$final_comma"); do
|
|
printf " {\n"
|
|
printf " \"entry_id\" : \"%s\"\n" "${ENTRY_SET[$j]}"
|
|
printf " },\n"
|
|
done
|
|
printf " {\n"
|
|
printf " \"entry_id\" : \"%s\"\n" "${ENTRY_SET[$final]}"
|
|
printf " }\n"
|
|
;;
|
|
esac
|
|
printf " ]\n"
|
|
|
|
# write the end of the temporary author_handle JSON file
|
|
#
|
|
printf "}\n"
|
|
|
|
} > "$TMP_FILENAME"
|
|
|
|
# update author_handle JSON file if needed
|
|
#
|
|
if cmp -s "$TMP_FILENAME" "$JSON_FILENAME"; then
|
|
|
|
# case: .entry.json did not change
|
|
#
|
|
if [[ $V_FLAG -ge 5 ]]; then
|
|
echo "$0: debug[5]: author_handle JSON file file did not change: $JSON_FILENAME" 1>&2
|
|
fi
|
|
|
|
else
|
|
|
|
# case: .entry.json file changed, update the file
|
|
#
|
|
if [[ $V_FLAG -ge 5 ]]; then
|
|
echo "$0: debug[5]: about to: mv -f -- $TMP_FILENAME $JSON_FILENAME" 1>&2
|
|
fi
|
|
if [[ $V_FLAG -ge 3 ]]; then
|
|
mv -f -v -- "$TMP_FILENAME" "$JSON_FILENAME" 1>&2
|
|
status="$?"
|
|
else
|
|
mv -f -- "$TMP_FILENAME" "$JSON_FILENAME" 1>&2
|
|
status="$?"
|
|
fi
|
|
if [[ $status -ne 0 ]]; then
|
|
echo "$0: ERROR: in write_author_handle_file: mv -f -- $TMP_FILENAME $JSON_FILENAME filed," \
|
|
"error code: $status" 1>&2
|
|
return 2
|
|
elif [[ $V_FLAG -ge 1 ]]; then
|
|
echo "$0: debug[1]: updated author_handle JSON file: $JSON_FILENAME" 1>&2
|
|
fi
|
|
if [[ ! -s $JSON_FILENAME ]]; then
|
|
echo "$0: ERROR: in write_author_handle_file: not a non-empty author_handle JSON file: $JSON_FILENAME" 1>&2
|
|
return 3
|
|
fi
|
|
fi
|
|
|
|
# all OK
|
|
#
|
|
return 0
|
|
}
|
|
|
|
|
|
# parse command line
|
|
#
|
|
while getopts :hv:Vd:c:g:i:T:nN flag; do
|
|
case "$flag" in
|
|
h) echo "$USAGE" 1>&2
|
|
exit 2
|
|
;;
|
|
v) V_FLAG="$OPTARG"
|
|
;;
|
|
V) echo "$VERSION"
|
|
exit 2
|
|
;;
|
|
d) TOPDIR="$OPTARG"
|
|
;;
|
|
c) CHKENTRY_TOOL="$OPTARG"
|
|
;;
|
|
g) GEN_README_TOOL="$OPTARG"
|
|
;;
|
|
i) INPUT_DATA_FILE="$OPTARG"
|
|
;;
|
|
T) TARBALL_DIR="$OPTARG"
|
|
;;
|
|
n) NOOP="-n"
|
|
;;
|
|
N) DO_NOT_PROCESS="-N"
|
|
;;
|
|
\?) echo "$0: ERROR: invalid option: -$OPTARG" 1>&2
|
|
echo 1>&2
|
|
echo "$USAGE" 1>&2
|
|
exit 3
|
|
;;
|
|
:) echo "$0: ERROR: option -$OPTARG requires an argument" 1>&2
|
|
echo 1>&2
|
|
echo "$USAGE" 1>&2
|
|
exit 3
|
|
;;
|
|
*) echo "$0: ERROR: unexpected value from getopts: $flag" 1>&2
|
|
echo 1>&2
|
|
echo "$USAGE" 1>&2
|
|
exit 3
|
|
;;
|
|
esac
|
|
done
|
|
#
|
|
# remove the options
|
|
#
|
|
shift $(( OPTIND - 1 ));
|
|
#
|
|
if [[ $V_FLAG -ge 5 ]]; then
|
|
echo "$0: debug[5]: file argument count: $#" 1>&2
|
|
fi
|
|
#
|
|
# verify arg count and parse args
|
|
#
|
|
if [[ $# -ne 1 ]]; then
|
|
echo "$0: ERROR: expected 1 arg, found: $#" 1>&2
|
|
echo 1>&2
|
|
echo "$USAGE" 1>&2
|
|
exit 3
|
|
fi
|
|
export ENTRY_PATH="$1"
|
|
|
|
|
|
# set umask to avoid group writable files
|
|
#
|
|
umask 0022
|
|
|
|
|
|
# if -i input_data, replace stdin with the input data file
|
|
#
|
|
if [[ -n $INPUT_DATA_FILE ]]; then
|
|
if [[ ! -e $INPUT_DATA_FILE ]]; then
|
|
echo "$0: ERROR: input data file does not exist: $INPUT_DATA_FILE" 1>&2
|
|
exit 3
|
|
fi
|
|
if [[ ! -f $INPUT_DATA_FILE ]]; then
|
|
echo "$0: ERROR: input data filetop is not a regular file: $INPUT_DATA_FILE" 1>&2
|
|
exit 3
|
|
fi
|
|
if [[ ! -r $INPUT_DATA_FILE ]]; then
|
|
echo "$0: ERROR: input data filetop is not a readable file: $INPUT_DATA_FILE" 1>&2
|
|
exit 3
|
|
fi
|
|
if [[ ! -s $INPUT_DATA_FILE ]]; then
|
|
echo "$0: ERROR: input data filetop is not a non-empty readable file: $INPUT_DATA_FILE" 1>&2
|
|
exit 3
|
|
fi
|
|
exec 0<"$INPUT_DATA_FILE"
|
|
fi
|
|
|
|
|
|
# verify that we have a topdir directory
|
|
#
|
|
REPO_NAME=$(basename "$REPO_TOP_URL")
|
|
export REPO_NAME
|
|
if [[ -z $TOPDIR ]]; then
|
|
echo "$0: ERROR: cannot find top of git repo directory" 1>&2
|
|
echo "$0: Notice: if needed: $GIT_TOOL clone $REPO_TOP_URL; cd $REPO_NAME" 1>&2
|
|
exit 6
|
|
fi
|
|
if [[ ! -e $TOPDIR ]]; then
|
|
echo "$0: ERROR: TOPDIR does not exist: $TOPDIR" 1>&2
|
|
echo "$0: Notice: if needed: $GIT_TOOL clone $REPO_TOP_URL; cd $REPO_NAME" 1>&2
|
|
exit 6
|
|
fi
|
|
if [[ ! -d $TOPDIR ]]; then
|
|
echo "$0: ERROR: TOPDIR is not a directory: $TOPDIR" 1>&2
|
|
echo "$0: Notice: if needed: $GIT_TOOL clone $REPO_TOP_URL; cd $REPO_NAME" 1>&2
|
|
exit 6
|
|
fi
|
|
|
|
|
|
# verify that we have a bin subdirectory
|
|
#
|
|
export BIN_PATH="$TOPDIR/bin"
|
|
if [[ ! -d $BIN_PATH ]]; then
|
|
echo "$0: ERROR: bin is not a directory under topdir: $BIN_PATH" 1>&2
|
|
exit 6
|
|
fi
|
|
export BIN_DIR="bin"
|
|
|
|
|
|
# cd to topdir
|
|
#
|
|
if [[ ! -e $TOPDIR ]]; then
|
|
echo "$0: ERROR: cannot cd to non-existent path: $TOPDIR" 1>&2
|
|
exit 6
|
|
fi
|
|
if [[ ! -d $TOPDIR ]]; then
|
|
echo "$0: ERROR: cannot cd to a non-directory: $TOPDIR" 1>&2
|
|
exit 6
|
|
fi
|
|
export CD_FAILED
|
|
if [[ $V_FLAG -ge 5 ]]; then
|
|
echo "$0: debug[5]: about to: cd $TOPDIR" 1>&2
|
|
fi
|
|
cd "$TOPDIR" || CD_FAILED="true"
|
|
if [[ -n $CD_FAILED ]]; then
|
|
echo "$0: ERROR: cd $TOPDIR failed" 1>&2
|
|
exit 6
|
|
fi
|
|
if [[ $V_FLAG -ge 3 ]]; then
|
|
echo "$0: debug[3]: now in directory: $(/bin/pwd)" 1>&2
|
|
fi
|
|
|
|
|
|
# verify we have a non-empty readable .top file
|
|
#
|
|
export TOP_FILE=".top"
|
|
if [[ ! -e $TOP_FILE ]]; then
|
|
echo "$0: ERROR: .top does not exist: $TOP_FILE" 1>&2
|
|
exit 6
|
|
fi
|
|
if [[ ! -f $TOP_FILE ]]; then
|
|
echo "$0: ERROR: .top is not a regular file: $TOP_FILE" 1>&2
|
|
exit 6
|
|
fi
|
|
if [[ ! -r $TOP_FILE ]]; then
|
|
echo "$0: ERROR: .top is not a readable file: $TOP_FILE" 1>&2
|
|
exit 6
|
|
fi
|
|
if [[ ! -s $TOP_FILE ]]; then
|
|
echo "$0: ERROR: .top is not a non-empty readable file: $TOP_FILE" 1>&2
|
|
exit 6
|
|
fi
|
|
|
|
|
|
# verify we have a non-empty readable .allyear file
|
|
#
|
|
export ALLYEAR=".allyear"
|
|
if [[ ! -e $ALLYEAR ]]; then
|
|
echo "$0: ERROR: .allyear does not exist: $ALLYEAR" 1>&2
|
|
exit 6
|
|
fi
|
|
if [[ ! -f $ALLYEAR ]]; then
|
|
echo "$0: ERROR: .allyear is not a regular file: $ALLYEAR" 1>&2
|
|
exit 6
|
|
fi
|
|
if [[ ! -r $ALLYEAR ]]; then
|
|
echo "$0: ERROR: .allyear is not a readable file: $ALLYEAR" 1>&2
|
|
exit 6
|
|
fi
|
|
if [[ ! -s $ALLYEAR ]]; then
|
|
echo "$0: ERROR: .allyear is not a non-empty writable file: $ALLYEAR" 1>&2
|
|
exit 6
|
|
fi
|
|
|
|
|
|
# verify that the bin/md2html.sh tool is executable
|
|
#
|
|
export MD2HTML_SH="$BIN_DIR/md2html.sh"
|
|
if [[ ! -e $MD2HTML_SH ]]; then
|
|
echo "$0: ERROR: bin/md2html.sh does not exist: $MD2HTML_SH" 1>&2
|
|
exit 5
|
|
fi
|
|
if [[ ! -f $MD2HTML_SH ]]; then
|
|
echo "$0: ERROR: bin/md2html.sh is not a regular file: $MD2HTML_SH" 1>&2
|
|
exit 5
|
|
fi
|
|
if [[ ! -x $MD2HTML_SH ]]; then
|
|
echo "$0: ERROR: bin/md2html.sh is not an executable file: $MD2HTML_SH" 1>&2
|
|
exit 5
|
|
fi
|
|
|
|
|
|
# verify that the bin/othermd2html.sh tool is executable
|
|
#
|
|
export OTHERMD2HTML_SH="$BIN_DIR/othermd2html.sh"
|
|
if [[ ! -e $OTHERMD2HTML_SH ]]; then
|
|
echo "$0: ERROR: bin/othermd2html.sh does not exist: $OTHERMD2HTML_SH" 1>&2
|
|
exit 5
|
|
fi
|
|
if [[ ! -f $OTHERMD2HTML_SH ]]; then
|
|
echo "$0: ERROR: bin/othermd2html.sh is not a regular file: $OTHERMD2HTML_SH" 1>&2
|
|
exit 5
|
|
fi
|
|
if [[ ! -x $OTHERMD2HTML_SH ]]; then
|
|
echo "$0: ERROR: bin/othermd2html.sh is not an executable file: $OTHERMD2HTML_SH" 1>&2
|
|
exit 5
|
|
fi
|
|
|
|
|
|
# verify that the bin/jval-wrapper.sh tool is executable
|
|
#
|
|
JVAL_WRAPPER="$BIN_DIR/jval-wrapper.sh"
|
|
if [[ ! -e $JVAL_WRAPPER ]]; then
|
|
echo "$0: ERROR: bin/jval-wrapper.sh does not exist: $JVAL_WRAPPER" 1>&2
|
|
exit 5
|
|
fi
|
|
if [[ ! -f $JVAL_WRAPPER ]]; then
|
|
echo "$0: ERROR: bin/jval-wrapper.sh is not a regular file: $JVAL_WRAPPER" 1>&2
|
|
exit 5
|
|
fi
|
|
if [[ ! -x $JVAL_WRAPPER ]]; then
|
|
echo "$0: ERROR: bin/jval-wrapper.sh is not an executable file: $JVAL_WRAPPER" 1>&2
|
|
exit 5
|
|
fi
|
|
|
|
|
|
# verify that ENTRY_PATH is a entry directory
|
|
#
|
|
if [[ ! -d $ENTRY_PATH ]]; then
|
|
echo "$0: ERROR: arg is not a directory: $ENTRY_PATH" 1>&2
|
|
exit 3
|
|
fi
|
|
if [[ ! -w $ENTRY_PATH ]]; then
|
|
echo "$0: ERROR: arg is not a writable directory: $ENTRY_PATH" 1>&2
|
|
exit 3
|
|
fi
|
|
export YEAR_DIR=${ENTRY_PATH%%/*}
|
|
if [[ -z $YEAR_DIR ]]; then
|
|
echo "$0: ERROR: arg not in YYYY/dir form: $ENTRY_PATH" 1>&2
|
|
exit 3
|
|
fi
|
|
export ENTRY_DIR=${ENTRY_PATH#*/}
|
|
if [[ -z $ENTRY_DIR ]]; then
|
|
echo "$0: ERROR: arg: $ENTRY_PATH not in $YEAR_DIR/dir form: $ENTRY_PATH" 1>&2
|
|
exit 3
|
|
fi
|
|
if [[ $ENTRY_DIR = */* ]]; then
|
|
echo "$0: ERROR: dir from arg: $ENTRY_PATH contains a /: $ENTRY_DIR" 1>&2
|
|
exit 3
|
|
fi
|
|
if [[ ! -d $YEAR_DIR ]]; then
|
|
echo "$0: ERROR: YYYY from arg: $ENTRY_PATH is not a directory: $YEAR_DIR" 1>&2
|
|
exit 3
|
|
fi
|
|
export ENTRY_ID="${YEAR_DIR}_${ENTRY_DIR}"
|
|
export DOT_YEAR="$YEAR_DIR/.year"
|
|
# Now that we have moved to topdir, form and verify YYYY_DIR is a writable directory
|
|
export YYYY_DIR="$YEAR_DIR/$ENTRY_DIR"
|
|
if [[ ! -e $YYYY_DIR ]]; then
|
|
echo "$0: ERROR: YYYY/dir from arg: $ENTRY_PATH does not exist: $YYYY_DIR" 1>&2
|
|
exit 6
|
|
fi
|
|
if [[ ! -d $YYYY_DIR ]]; then
|
|
echo "$0: ERROR: YYYY/dir from arg: $ENTRY_PATH is not a directory: $YYYY_DIR" 1>&2
|
|
exit 6
|
|
fi
|
|
if [[ ! -w $YYYY_DIR ]]; then
|
|
echo "$0: ERROR: YYYY/dir from arg: $ENTRY_PATH is not a writable directory: $YYYY_DIR" 1>&2
|
|
exit 6
|
|
fi
|
|
|
|
|
|
# determine files that are found in and/or will be created in an entry
|
|
#
|
|
export INFO_JSON="$YYYY_DIR/.info.json"
|
|
export AUTH_JSON="$YYYY_DIR/.auth.json"
|
|
export AUTH_JSON_XZ="$YYYY_DIR/.auth.json.xz"
|
|
export REMARKS_MD="$YYYY_DIR/remarks.md"
|
|
export TAR_BZ2="$YYYY_DIR/$ENTRY_ID.tar.bz2"
|
|
export ENTRY_JSON="$YYYY_DIR/.entry.json"
|
|
export DOT_GITIGNORE="$YYYY_DIR/.gitignore"
|
|
export TRY_SH="$YYYY_DIR/try.sh"
|
|
export TRY_ALT_SH="$YYYY_DIR/try.alt.sh"
|
|
export DOT_PATH="$YYYY_DIR/.path"
|
|
export README_MD="$YYYY_DIR/README.md"
|
|
export INDEX_HTML="$YYYY_DIR/index.html"
|
|
|
|
|
|
# determine template files
|
|
#
|
|
export TEMPLATE_DIR="template"
|
|
export NEXT_DIR="next"
|
|
export TEMPLATE_ENTRY_DIR="$TEMPLATE_DIR/entry"
|
|
export TEMPLATE_GITIGNORE="$TEMPLATE_ENTRY_DIR/gitignore"
|
|
export TEMPLATE_README_MD_HEAD="$TEMPLATE_ENTRY_DIR/README.md.head"
|
|
export TEMPLATE_README_MD_TAIL="$TEMPLATE_ENTRY_DIR/README.md.tail"
|
|
export TEMPLATE_TRY_SH="$TEMPLATE_ENTRY_DIR/try.sh.judging"
|
|
|
|
|
|
# determine TARBALL filename
|
|
#
|
|
NOW=$(date '+%Y%m%d.%H%M%S')
|
|
export NOW
|
|
export TARBALL="$TARBALL_DIR/$ENTRY_ID.mods.$NOW.tar.bz2"
|
|
|
|
|
|
# print running info if verbose
|
|
#
|
|
# If -v 3 or higher, print exported variables in order that they were exported.
|
|
#
|
|
if [[ $V_FLAG -ge 3 ]]; then
|
|
echo "$0: debug[3]: LANG=$LANG" 1>&2
|
|
echo "$0: debug[3]: LC_CTYPE=$LC_CTYPE" 1>&2
|
|
echo "$0: debug[3]: LC_NUMERIC=$LC_NUMERIC" 1>&2
|
|
echo "$0: debug[3]: LC_TIME=$LC_TIME" 1>&2
|
|
echo "$0: debug[3]: LC_COLLATE=$LC_COLLATE" 1>&2
|
|
echo "$0: debug[3]: LC_MONETARY=$LC_MONETARY" 1>&2
|
|
echo "$0: debug[3]: LC_MESSAGES=$LC_MESSAGES" 1>&2
|
|
echo "$0: debug[3]: LC_PAPER=$LC_PAPER" 1>&2
|
|
echo "$0: debug[3]: LC_NAME=$LC_NAME" 1>&2
|
|
echo "$0: debug[3]: LC_ADDRESS=$LC_ADDRESS" 1>&2
|
|
echo "$0: debug[3]: LC_TELEPHONE=$LC_TELEPHONE" 1>&2
|
|
echo "$0: debug[3]: LC_MEASUREMENT=$LC_MEASUREMENT" 1>&2
|
|
echo "$0: debug[3]: LC_IDENTIFICATION=$LC_IDENTIFICATION" 1>&2
|
|
echo "$0: debug[3]: LC_ALL=$LC_ALL" 1>&2
|
|
echo "$0: debug[3]: VERSION=$VERSION" 1>&2
|
|
echo "$0: debug[3]: NAME=$NAME" 1>&2
|
|
echo "$0: debug[3]: V_FLAG=$V_FLAG" 1>&2
|
|
echo "$0: debug[3]: GIT_TOOL=$GIT_TOOL" 1>&2
|
|
echo "$0: debug[3]: TOPDIR=$TOPDIR" 1>&2
|
|
echo "$0: debug[3]: CHKENTRY_TOOL=$CHKENTRY_TOOL" 1>&2
|
|
echo "$0: debug[3]: GEN_README_TOOL=$GEN_README_TOOL" 1>&2
|
|
echo "$0: debug[3]: VERGE=$VERGE" 1>&2
|
|
echo "$0: debug[3]: JSTRDECODE=$JSTRDECODE" 1>&2
|
|
echo "$0: debug[3]: MIN_JSTRDECODE_VERSION=$MIN_JSTRDECODE_VERSION" 1>&2
|
|
echo "$0: debug[3]: JSTRDECODE_VERSION=$JSTRDECODE_VERSION" 1>&2
|
|
echo "$0: debug[3]: GTAR_TOOL=$GTAR_TOOL" 1>&2
|
|
echo "$0: debug[3]: REPO_TOP_URL=$REPO_TOP_URL" 1>&2
|
|
echo "$0: debug[3]: REPO_URL=$REPO_URL" 1>&2
|
|
echo "$0: debug[3]: JPARSE_TOOL=$JPARSE_TOOL" 1>&2
|
|
echo "$0: debug[3]: MKIOCCCENTRY_REPO=$MKIOCCCENTRY_REPO" 1>&2
|
|
echo "$0: debug[3]: INPUT_DATA_FILE=$INPUT_DATA_FILE" 1>&2
|
|
echo "$0: debug[3]: NO_COMMENT=$NO_COMMENT" 1>&2
|
|
echo "$0: debug[3]: ENTRY_JSON_FORMAT_VERSION=$ENTRY_JSON_FORMAT_VERSION" 1>&2
|
|
echo "$0: debug[3]: AUTHOR_JSON_FORMAT_VERSION=$AUTHOR_JSON_FORMAT_VERSION" 1>&2
|
|
echo "$0: debug[3]: NOOP=$NOOP" 1>&2
|
|
echo "$0: debug[3]: DO_NOT_PROCESS=$DO_NOT_PROCESS" 1>&2
|
|
echo "$0: debug[3]: ENTRY_PATH=$ENTRY_PATH" 1>&2
|
|
echo "$0: debug[3]: REPO_NAME=$REPO_NAME" 1>&2
|
|
echo "$0: debug[3]: CD_FAILED=$CD_FAILED" 1>&2
|
|
echo "$0: debug[3]: TOP_FILE=$TOP_FILE" 1>&2
|
|
echo "$0: debug[3]: ALLYEAR=$ALLYEAR" 1>&2
|
|
echo "$0: debug[3]: BIN_PATH=$BIN_PATH" 1>&2
|
|
echo "$0: debug[3]: BIN_DIR=$BIN_DIR" 1>&2
|
|
echo "$0: debug[3]: MD2HTML_SH=$MD2HTML_SH" 1>&2
|
|
echo "$0: debug[3]: OTHERMD2HTML_SH=$OTHERMD2HTML_SH" 1>&2
|
|
echo "$0: debug[3]: JVAL_WRAPPER=$JVAL_WRAPPER" 1>&2
|
|
echo "$0: debug[3]: YEAR_DIR=$YEAR_DIR" 1>&2
|
|
echo "$0: debug[3]: ENTRY_DIR=$ENTRY_DIR" 1>&2
|
|
echo "$0: debug[3]: ENTRY_ID=$ENTRY_ID" 1>&2
|
|
echo "$0: debug[3]: DOT_YEAR=$DOT_YEAR" 1>&2
|
|
echo "$0: debug[3]: YYYY_DIR=$YYYY_DIR" 1>&2
|
|
echo "$0: debug[3]: INFO_JSON=$INFO_JSON" 1>&2
|
|
echo "$0: debug[3]: AUTH_JSON=$AUTH_JSON" 1>&2
|
|
echo "$0: debug[3]: AUTH_JSON_XZ=$AUTH_JSON_XZ" 1>&2
|
|
echo "$0: debug[3]: REMARKS_MD=$REMARKS_MD" 1>&2
|
|
echo "$0: debug[3]: TAR_BZ2=$TAR_BZ2" 1>&2
|
|
echo "$0: debug[3]: ENTRY_JSON=$ENTRY_JSON" 1>&2
|
|
echo "$0: debug[3]: DOT_GITIGNORE=$DOT_GITIGNORE" 1>&2
|
|
echo "$0: debug[3]: TRY_SH=$TRY_SH" 1>&2
|
|
echo "$0: debug[3]: TRY_ALT_SH=$TRY_ALT_SH" 1>&2
|
|
echo "$0: debug[3]: DOT_PATH=$DOT_PATH" 1>&2
|
|
echo "$0: debug[3]: README_MD=$README_MD" 1>&2
|
|
echo "$0: debug[3]: INDEX_HTML=$INDEX_HTML" 1>&2
|
|
echo "$0: debug[3]: TEMPLATE_DIR=$TEMPLATE_DIR" 1>&2
|
|
echo "$0: debug[3]: NEXT_DIR=$NEXT_DIR" 1>&2
|
|
echo "$0: debug[3]: TEMPLATE_ENTRY_DIR=$TEMPLATE_ENTRY_DIR" 1>&2
|
|
echo "$0: debug[3]: TEMPLATE_GITIGNORE=$TEMPLATE_GITIGNORE" 1>&2
|
|
echo "$0: debug[3]: TEMPLATE_README_MD_HEAD=$TEMPLATE_README_MD_HEAD" 1>&2
|
|
echo "$0: debug[3]: TEMPLATE_README_MD_TAIL=$TEMPLATE_README_MD_TAIL" 1>&2
|
|
echo "$0: debug[3]: TARBALL_DIR=$TARBALL_DIR" 1>&2
|
|
echo "$0: debug[3]: NOW=$NOW" 1>&2
|
|
echo "$0: debug[3]: TARBALL=$TARBALL" 1>&2
|
|
fi
|
|
|
|
|
|
# firewall - verify template files
|
|
#
|
|
if [[ ! -d $TEMPLATE_DIR ]]; then
|
|
echo "$0: ERROR: missing template directory: $TEMPLATE_DIR" 1>&2
|
|
exit 6
|
|
fi
|
|
if [[ ! -d $TEMPLATE_ENTRY_DIR ]]; then
|
|
echo "$0: ERROR: missing template/entry directory: $TEMPLATE_ENTRY_DIR" 1>&2
|
|
exit 6
|
|
fi
|
|
if [[ ! -f $TEMPLATE_GITIGNORE ]]; then
|
|
echo "$0: ERROR: missing template gitignore file: $TEMPLATE_GITIGNORE" 1>&2
|
|
exit 6
|
|
fi
|
|
if [[ ! -f $TEMPLATE_README_MD_HEAD ]]; then
|
|
echo "$0: ERROR: missing template README.md.head file: $TEMPLATE_README_MD_HEAD" 1>&2
|
|
exit 6
|
|
fi
|
|
if [[ ! -f $TEMPLATE_README_MD_TAIL ]]; then
|
|
echo "$0: ERROR: missing template README.md.tail file: $TEMPLATE_README_MD_TAIL" 1>&2
|
|
exit 6
|
|
fi
|
|
if [[ ! -d $NEXT_DIR ]]; then
|
|
echo "$0: ERROR: missing next directory: $NEXT_DIR" 1>&2
|
|
exit 6
|
|
fi
|
|
if [[ ! -f $TEMPLATE_TRY_SH ]]; then
|
|
echo "$0: ERROR: missing template/entry/try.sh.judging: $TEMPLATE_TRY_SH" 1>&2
|
|
exit 6
|
|
fi
|
|
|
|
|
|
# firewall - verify chkentry tool
|
|
#
|
|
if [[ ! -e $CHKENTRY_TOOL ]]; then
|
|
echo "$0: ERROR: chkentry file does not exist: $CHKENTRY_TOOL" 1>&2
|
|
echo "$0: Notice: if needed: $GIT_TOOL clone $MKIOCCCENTRY_REPO; cd mkiocccentry" 1>&2
|
|
echo "$0: Notice: then if needed: make clobber all install" 1>&2
|
|
exit 5
|
|
fi
|
|
if [[ ! -f $CHKENTRY_TOOL ]]; then
|
|
echo "$0: ERROR: chkentry is not a file: $CHKENTRY_TOOL" 1>&2
|
|
echo "$0: Notice: if needed: $GIT_TOOL clone $MKIOCCCENTRY_REPO; cd mkiocccentry" 1>&2
|
|
echo "$0: Notice: then if needed: make clobber all install" 1>&2
|
|
exit 5
|
|
fi
|
|
if [[ ! -x $CHKENTRY_TOOL ]]; then
|
|
echo "$0: ERROR: cannot find an executable chkentry tool: $CHKENTRY_TOOL" 1>&2
|
|
echo "$0: Notice: if needed: $GIT_TOOL clone $MKIOCCCENTRY_REPO; cd mkiocccentry" 1>&2
|
|
echo "$0: Notice: then if needed: make clobber all install" 1>&2
|
|
exit 5
|
|
fi
|
|
|
|
|
|
# firewall - verify gen-readme.sh tool
|
|
#
|
|
if [[ ! -e $GEN_README_TOOL ]]; then
|
|
echo "$0: ERROR: gen-readme.sh file does not exist: $GEN_README_TOOL" 1>&2
|
|
exit 5
|
|
fi
|
|
if [[ ! -f $GEN_README_TOOL ]]; then
|
|
echo "$0: ERROR: gen-readme.sh is not a file: $GEN_README_TOOL" 1>&2
|
|
exit 5
|
|
fi
|
|
if [[ ! -x $GEN_README_TOOL ]]; then
|
|
echo "$0: ERROR: cannot find an executable gen-readme.sh tool: $GEN_README_TOOL" 1>&2
|
|
exit 5
|
|
fi
|
|
|
|
|
|
# verify that YEAR is already in .top
|
|
#
|
|
if ! grep -E -q "^$YEAR_DIR$" "$TOP_FILE"; then
|
|
echo "$0: ERROR: YEAR_DIR: $YEAR_DIR not found in: $TOP_FILE" 1>&2
|
|
echo "$0: notice: consider running: bin/new-year.sh $YEAR_DIR -v 1" 1>&2
|
|
exit 6
|
|
fi
|
|
|
|
|
|
# case: we have .auth.json.xz but not .auth.json
|
|
#
|
|
# Form a .auth.json from .auth.json.xz
|
|
#
|
|
if [[ -f $AUTH_JSON_XZ && ! -f $AUTH_JSON ]]; then
|
|
if [[ -z $NOOP ]]; then
|
|
|
|
if [[ $V_FLAG -ge 3 ]]; then
|
|
echo "$0: debug[3]: about to execute:" \
|
|
"xzcat $AUTH_JSON_XZ > $AUTH_JSON" 1>&2
|
|
fi
|
|
xzcat "$AUTH_JSON_XZ" > "$AUTH_JSON"
|
|
status="$?"
|
|
if [[ $status -ne 0 ]]; then
|
|
echo "$0: ERROR:" \
|
|
"xzcat $AUTH_JSON_XZ > $AUTH_JSON failed, error: $status" 1>&2
|
|
exit 7
|
|
fi
|
|
if [[ $V_FLAG -ge 3 ]]; then
|
|
echo "$0: debug[3]: about to execute:" \
|
|
"chmod -v 0444 $AUTH_JSON" 1>&2
|
|
chmod -v 0444 "$AUTH_JSON"
|
|
status="$?"
|
|
if [[ $status -ne 0 ]]; then
|
|
echo "$0: ERROR:" \
|
|
"chmod -v 0444 $AUTH_JSON failed, error: $status" 1>&2
|
|
exit 7
|
|
fi
|
|
else
|
|
chmod 0444 "$AUTH_JSON"
|
|
status="$?"
|
|
if [[ $status -ne 0 ]]; then
|
|
echo "$0: ERROR:" \
|
|
"chmod 0444 $AUTH_JSON failed, error: $status" 1>&2
|
|
exit 7
|
|
fi
|
|
fi
|
|
|
|
elif [[ $V_FLAG -ge 3 ]]; then
|
|
echo "$0: debug[3]: because of -n, $AUTH_JSON file was not formed" 1>&2
|
|
fi
|
|
fi
|
|
|
|
|
|
# verify .info.json and .auth.json are readable non-empty files
|
|
#
|
|
if [[ ! -e $INFO_JSON ]]; then
|
|
echo "$0: ERROR: .info.json does not exist: $INFO_JSON" 1>&2
|
|
exit 6
|
|
fi
|
|
if [[ ! -f $INFO_JSON ]]; then
|
|
echo "$0: ERROR: .info.json is not a regular file: $INFO_JSON" 1>&2
|
|
exit 6
|
|
fi
|
|
if [[ ! -r $INFO_JSON ]]; then
|
|
echo "$0: ERROR: .info.json is not a readable file: $INFO_JSON" 1>&2
|
|
exit 6
|
|
fi
|
|
if [[ ! -s $INFO_JSON ]]; then
|
|
echo "$0: ERROR: .info.json is not a non-empty readable file: $INFO_JSON" 1>&2
|
|
exit 6
|
|
fi
|
|
if [[ -z $NOOP ]]; then
|
|
if [[ ! -e $AUTH_JSON ]]; then
|
|
echo "$0: ERROR: .auth.json does not exist: $AUTH_JSON" 1>&2
|
|
exit 6
|
|
fi
|
|
if [[ ! -f $AUTH_JSON ]]; then
|
|
echo "$0: ERROR: .auth.json is not a regular file: $AUTH_JSON" 1>&2
|
|
exit 6
|
|
fi
|
|
if [[ ! -r $AUTH_JSON ]]; then
|
|
echo "$0: ERROR: .auth.json is not a readable file: $AUTH_JSON" 1>&2
|
|
exit 6
|
|
fi
|
|
if [[ ! -s $AUTH_JSON ]]; then
|
|
echo "$0: ERROR: .auth.json is not a non-empty readable file: $AUTH_JSON" 1>&2
|
|
exit 6
|
|
fi
|
|
elif [[ $V_FLAG -ge 3 ]]; then
|
|
echo "$0: debug[3]: because of -n, $AUTH_JSON file not checked" 1>&2
|
|
fi
|
|
|
|
|
|
# initialize the list of files that we might tar
|
|
#
|
|
unset TAR_FILE_SET
|
|
declare -ag TAR_FILE_SET
|
|
#
|
|
for FILE in "$INFO_JSON" "$AUTH_JSON" "$REMARKS_MD" "$README_MD" "$INDEX_HTML" "$TAR_BZ2"; do
|
|
if [[ -f $FILE ]]; then
|
|
TAR_FILE_SET+=("$FILE")
|
|
fi
|
|
done
|
|
#
|
|
# add each author/author_handle.json file referenced by .auth.json file that exists
|
|
#
|
|
unset AUTHOR_HANDLE_SET
|
|
declare -ag AUTHOR_HANDLE_SET
|
|
#
|
|
export PATTERN
|
|
PATTERN='$..author_handle'
|
|
if [[ $V_FLAG -ge 5 ]]; then
|
|
echo "$0: debug[5]: about to run: $JVAL_WRAPPER -b -q -- $AUTH_JSON '$PATTERN'" 1>&2
|
|
fi
|
|
export FOUND_AUTHOR_HANDLES
|
|
FOUND_AUTHOR_HANDLES=$("$JVAL_WRAPPER" -b -q -- "$AUTH_JSON" "$PATTERN")
|
|
status="$?"
|
|
if [[ $status -ne 0 ]]; then
|
|
echo "$0: ERROR: $JVAL_WRAPPER -b -q -- $AUTH_JSON '$PATTERN' failed," \
|
|
"error code: $status" 1>&2
|
|
exit 10
|
|
fi
|
|
if [[ -z $FOUND_AUTHOR_HANDLES ]]; then
|
|
echo "$0: ERROR: found no author_handle's in: $AUTH_JSON" 1>&2
|
|
exit 11
|
|
fi
|
|
for AUTHOR_HANDLE in $FOUND_AUTHOR_HANDLES; do
|
|
# add referenced by .auth.json if it exists
|
|
AUTHOR_HANDLE_JSON="author/$AUTHOR_HANDLE.json"
|
|
if [[ -f $AUTHOR_HANDLE_JSON ]]; then
|
|
TAR_FILE_SET+=("$AUTHOR_HANDLE_JSON")
|
|
fi
|
|
# remember the author_handle for later even if it doesn't exist
|
|
AUTHOR_HANDLE_SET+=("$AUTHOR_HANDLE")
|
|
done
|
|
#
|
|
if [[ $V_FLAG -ge 3 ]]; then
|
|
for index in "${!TAR_FILE_SET[@]}"; do
|
|
echo "$0: debug[3]: TAR_FILE_SET[$index]=${TAR_FILE_SET[$index]}" 1>&2
|
|
done
|
|
fi
|
|
|
|
|
|
# -N stops early before any processing is performed
|
|
#
|
|
if [[ -n $DO_NOT_PROCESS ]]; then
|
|
if [[ $V_FLAG -ge 3 ]]; then
|
|
echo "$0: debug[3]: arguments parsed, -N given, exiting 0" 1>&2
|
|
fi
|
|
exit 0
|
|
fi
|
|
|
|
|
|
# save files that might be added to or removed from the tarball
|
|
#
|
|
if [[ -z $NOOP ]]; then
|
|
if [[ $V_FLAG -ge 3 ]]; then
|
|
echo "$0: debug[3]: about to execute:" \
|
|
"TZ=UTC LC_ALL=C $GTAR_TOOL --sort=name" \
|
|
"--totals -jcvf $TARBALL ${TAR_FILE_SET[*]}" 1>&2
|
|
TZ=UTC LC_ALL=C "$GTAR_TOOL" --sort=name \
|
|
--totals -jcvf "$TARBALL" "${TAR_FILE_SET[@]}"
|
|
status="$?"
|
|
if [[ $status -ne 0 ]]; then
|
|
echo "$0: ERROR:" \
|
|
"TZ=UTC LC_ALL=C $GTAR_TOOL --sort=name" \
|
|
"--totals -jcvf $TARBALL ${TAR_FILE_SET[*]} failed, error: $status" 1>&2
|
|
exit 12
|
|
fi
|
|
|
|
# case: form the tarball silently
|
|
#
|
|
else
|
|
TZ=UTC LC_ALL=C "$GTAR_TOOL" --sort=name \
|
|
-jcf "$TARBALL" "${TAR_FILE_SET[@]}"
|
|
status="$?"
|
|
if [[ $status -ne 0 ]]; then
|
|
echo "$0: ERROR:" \
|
|
"TZ=UTC LC_ALL=C $GTAR_TOOL --sort=name" \
|
|
"-jcf $TARBALL ${TAR_FILE_SET[*]} failed, error: $status" 1>&2
|
|
exit 13
|
|
fi
|
|
fi
|
|
elif [[ $V_FLAG -ge 3 ]]; then
|
|
echo "$0: debug[3]: because of -n, tarball not formed: $TARBALL" 1>&2
|
|
fi
|
|
|
|
|
|
# perform the semantic check on .info.json and .auth.json
|
|
#
|
|
if [[ $V_FLAG -ge 1 ]]; then
|
|
echo "$0: debug[1]: about to run: $CHKENTRY_TOOL -v 1" \
|
|
"-i .auth.json.xz -i .prev -i .submit.sh -i .txz -i .num.sh -i .orig" \
|
|
"-i .path -i README.md -i .gitignore -- $YYYY_DIR" 1>&2
|
|
"$CHKENTRY_TOOL" -v 1 -i .auth.json.xz -i .prev -i .submit.sh -i .txz -i .num.sh -i .orig \
|
|
-i .path -i README.md -i .gitignore -i .DS_Store -P -- "$YYYY_DIR"
|
|
status="$?"
|
|
if [[ $status -ne 0 ]]; then
|
|
echo "$0: ERROR: $CHKENTRY_TOOL -v 1 -i .auth.json.xz -i .prev -i .submit.sh -i .txz -i .num.sh -i .orig" \
|
|
"-i .path -i README.md -i .gitignore -i .DS_Store -P -- $YYYY_DIR failed," \
|
|
"error code: $status" 1>&2
|
|
exit 7
|
|
fi
|
|
else
|
|
"$CHKENTRY_TOOL" -i .auth.json.xz -i .prev -i .submit.sh -i .txz -i .num.sh -i .orig \
|
|
-i .path -i README.md -i .gitignore -i .DS_Store -P -- "$YYYY_DIR"
|
|
status="$?"
|
|
if [[ $status -ne 0 ]]; then
|
|
echo "$0: $CHKENTRY_TOOL -i .auth.json.xz -i .prev -i .submit.sh -i .txz -i .num.sh -i .orig" \
|
|
"-i .path -i README.md -i .gitignore -i .DS_Store -P -- $YYYY_DIR failed," \
|
|
"error code: $status" 1>&2
|
|
exit 7
|
|
fi
|
|
fi
|
|
|
|
|
|
# create a temporary .entry.json file
|
|
#
|
|
export TMP_ENTRY_JSON=".tmp.$NAME.ENTRY_JSON.$$.tmp"
|
|
if [[ $V_FLAG -ge 3 ]]; then
|
|
echo "$0: debug[3]: temporary .entry.json file: $TMP_ENTRY_JSON" 1>&2
|
|
fi
|
|
if [[ -z $NOOP ]]; then
|
|
trap 'rm -f $TMP_ENTRY_JSON; exit' 0 1 2 3 15
|
|
rm -f "$TMP_ENTRY_JSON"
|
|
if [[ -e $TMP_ENTRY_JSON ]]; then
|
|
echo "$0: ERROR: cannot remove temporary .entry.json file: $TMP_ENTRY_JSON" 1>&2
|
|
exit 14
|
|
fi
|
|
:> "$TMP_ENTRY_JSON"
|
|
if [[ ! -e $TMP_ENTRY_JSON ]]; then
|
|
echo "$0: ERROR: cannot create temporary .entry.json file: $TMP_ENTRY_JSON" 1>&2
|
|
exit 15
|
|
fi
|
|
elif [[ $V_FLAG -ge 3 ]]; then
|
|
echo "$0: debug[3]: because of -n, temporary .entry.json file is not used: $TMP_ENTRY_JSON" 1>&2
|
|
fi
|
|
|
|
|
|
# create a temporary author_handle JSON file
|
|
#
|
|
export TMP_AUTHOR_HANDLE_JSON=".tmp.$NAME.AUTHOR_HANDLE_JSON.$$.tmp"
|
|
if [[ $V_FLAG -ge 3 ]]; then
|
|
echo "$0: debug[3]: temporary author_handle file: $TMP_AUTHOR_HANDLE_JSON" 1>&2
|
|
fi
|
|
if [[ -z $NOOP ]]; then
|
|
trap 'rm -f $TMP_ENTRY_JSON $TMP_AUTHOR_HANDLE_JSON; exit' 0 1 2 3 15
|
|
rm -f "$TMP_AUTHOR_HANDLE_JSON"
|
|
if [[ -e $TMP_AUTHOR_HANDLE_JSON ]]; then
|
|
echo "$0: ERROR: cannot remove temporary author_handle file: $TMP_AUTHOR_HANDLE_JSON" 1>&2
|
|
exit 16
|
|
fi
|
|
:> "$TMP_AUTHOR_HANDLE_JSON"
|
|
if [[ ! -e $TMP_AUTHOR_HANDLE_JSON ]]; then
|
|
echo "$0: ERROR: cannot create temporary author_handle file: $TMP_AUTHOR_HANDLE_JSON" 1>&2
|
|
exit 17
|
|
fi
|
|
elif [[ $V_FLAG -ge 3 ]]; then
|
|
echo "$0: debug[3]: because of -n, temporary author_handle file is not used: $TMP_AUTHOR_HANDLE_JSON" 1>&2
|
|
fi
|
|
|
|
|
|
# create a temporary manifest.csv file
|
|
#
|
|
export TMP_MANIFEST_CSV=".tmp.$NAME.MANIFEST_CSV.$$.tmp"
|
|
if [[ $V_FLAG -ge 3 ]]; then
|
|
echo "$0: debug[3]: temporary manifest csv file: $TMP_MANIFEST_CSV" 1>&2
|
|
fi
|
|
if [[ -z $NOOP ]]; then
|
|
trap 'rm -f $TMP_ENTRY_JSON $TMP_AUTHOR_HANDLE_JSON $TMP_MANIFEST_CSV; exit' 0 1 2 3 15
|
|
rm -f "$TMP_MANIFEST_CSV"
|
|
if [[ -e $TMP_MANIFEST_CSV ]]; then
|
|
echo "$0: ERROR: cannot remove temporary manifest csv file: $TMP_MANIFEST_CSV" 1>&2
|
|
exit 18
|
|
fi
|
|
:> "$TMP_MANIFEST_CSV"
|
|
if [[ ! -e $TMP_MANIFEST_CSV ]]; then
|
|
echo "$0: ERROR: cannot create temporary manifest csv file: $TMP_MANIFEST_CSV" 1>&2
|
|
exit 19
|
|
fi
|
|
elif [[ $V_FLAG -ge 3 ]]; then
|
|
echo "$0: debug[3]: because of -n, temporary manifest csv file is not used: $TMP_MANIFEST_CSV" 1>&2
|
|
fi
|
|
|
|
|
|
# obtain title from .info.json
|
|
#
|
|
export PATTERN='$..title'
|
|
TITLE=$("$JVAL_WRAPPER" -b -q "$INFO_JSON" "$PATTERN")
|
|
export TITLE
|
|
if [[ -z $TITLE ]]; then
|
|
TITLE="${ENTRY_DIR}.${YEAR_DIR}"
|
|
echo "$0: Warning empty title for in $INFO_JSON, use $TITLE" 1>&2
|
|
fi
|
|
|
|
|
|
# obtain title from .info.json
|
|
#
|
|
export ABSTRACT='$..abstract'
|
|
ABSTRACT=$("$JVAL_WRAPPER" -b -q "$INFO_JSON" "$PATTERN")
|
|
export ABSTRACT
|
|
if [[ -z $ABSTRACT ]]; then
|
|
ABSTRACT="default abstract for ${YEAR_DIR}/${ENTRY_DIR}"
|
|
echo "$0: Warning empty abstreact for in $INFO_JSON, will use $ABSTRACT" 1>&2
|
|
fi
|
|
|
|
|
|
# case: without -n
|
|
#
|
|
export VALUE
|
|
if [[ -z $NOOP ]]; then
|
|
|
|
# form the start of the temporary .entry.json file
|
|
#
|
|
{
|
|
echo '{'
|
|
echo ' "no_comment" : "'"$NO_COMMENT"'",'
|
|
echo ' "entry_JSON_format_version" : "'"$ENTRY_JSON_FORMAT_VERSION"'",'
|
|
} > "$TMP_ENTRY_JSON"
|
|
|
|
# write the award to the temporary .entry.json file
|
|
#
|
|
VALUE=
|
|
prompt_string "award"
|
|
status="$?"
|
|
if [[ $status -ne 0 || -z $VALUE ]]; then
|
|
echo "$0: ERROR: prompt_string award failed," \
|
|
"error code: $status" 1>&2
|
|
exit 1
|
|
fi
|
|
{
|
|
# write award
|
|
#
|
|
echo " \"award\" : \"${VALUE}\","
|
|
|
|
# write IOCCC year to the temporary .entry.json file
|
|
#
|
|
echo " \"year\" : ${YEAR_DIR},"
|
|
|
|
# write entry directory to the temporary .entry.json file
|
|
#
|
|
echo " \"dir\" : \"${ENTRY_DIR}\","
|
|
|
|
# write entry_id to the temporary .entry.json file
|
|
#
|
|
echo " \"entry_id\" : \"${ENTRY_ID}\","
|
|
|
|
# write title to the temporary .entry.json file
|
|
#
|
|
echo " \"title\" : \"${TITLE}\","
|
|
|
|
# write abstract to the temporary .entry.json file
|
|
#
|
|
echo " \"abstract\" : \"${ABSTRACT}\","
|
|
|
|
# start the author_set JSON array
|
|
#
|
|
echo " \"author_set\" : ["
|
|
} >> "$TMP_ENTRY_JSON"
|
|
|
|
# process each author_handle
|
|
#
|
|
export i=0
|
|
# In the for loop below, we prefer to use individual redirects
|
|
#
|
|
# SC2129 (style): Consider using { cmd1; cmd2; } >> file instead of individual redirects
|
|
# https://www.shellcheck.net/wiki/SC2129
|
|
# shellcheck disable=SC2129
|
|
for AUTHOR_HANDLE in "${AUTHOR_HANDLE_SET[@]}"; do
|
|
|
|
# case: not the first author_handle
|
|
#
|
|
if [[ $i -ge 1 ]]; then
|
|
printf ",\n"
|
|
fi
|
|
|
|
# initialize the AUTHOR_INFO
|
|
#
|
|
unset AUTHOR_INFO
|
|
declare -Ag AUTHOR_INFO
|
|
AUTHOR_INFO[no_comment]="$NO_COMMENT"
|
|
AUTHOR_INFO[author_JSON_format_version]="$AUTHOR_JSON_FORMAT_VERSION"
|
|
AUTHOR_INFO[deprecated_twitter_handle]="null"
|
|
AUTHOR_INFO[author_handle]="$AUTHOR_HANDLE"
|
|
|
|
# parse an element value of the this particular author in the authors JSON array
|
|
#
|
|
PATTERN='$.authors['"$i"']'
|
|
if [[ $V_FLAG -ge 5 ]]; then
|
|
echo "$0: debug[5]: about to run: $JVAL_WRAPPER -b -q -- $AUTH_JSON '$PATTERN'" 1>&2
|
|
fi
|
|
export AUTHOR_DATA
|
|
AUTHOR_DATA=$("$JVAL_WRAPPER" -q -- "$AUTH_JSON" "$PATTERN")
|
|
status="$?"
|
|
if [[ $status -ne 0 ]]; then
|
|
echo "$0: ERROR: $JVAL_WRAPPER -q -- $AUTH_JSON '$PATTERN' failed," \
|
|
"error code: $status" 1>&2
|
|
exit 20
|
|
fi
|
|
if [[ -z $AUTHOR_DATA ]]; then
|
|
echo "$0: ERROR: found nothing for author[$i] in: $AUTH_JSON" 1>&2
|
|
exit 21
|
|
fi
|
|
export AUTHOR_PAST_WINNING_AUTHOR=
|
|
export AUTHOR_DEFAULT_HANDLE=
|
|
export AUTHOR_AUTHOR_NUMBER=
|
|
while read -r NAME VALUE; do
|
|
|
|
# parse name value
|
|
#
|
|
case "$NAME" in
|
|
name)
|
|
AUTHOR_INFO[name]="$VALUE"
|
|
;;
|
|
location_code)
|
|
AUTHOR_INFO[location_code]="$VALUE"
|
|
;;
|
|
email)
|
|
AUTHOR_INFO[email]="$VALUE"
|
|
;;
|
|
url)
|
|
AUTHOR_INFO[url]="$VALUE"
|
|
;;
|
|
alt_url)
|
|
AUTHOR_INFO[alt_url]="$VALUE"
|
|
;;
|
|
mastodon)
|
|
AUTHOR_INFO[mastodon]="$VALUE"
|
|
;;
|
|
github)
|
|
AUTHOR_INFO[github]="$VALUE"
|
|
;;
|
|
affiliation)
|
|
AUTHOR_INFO[affiliation]="$VALUE"
|
|
;;
|
|
past_winning_author)
|
|
AUTHOR_PAST_WINNING_AUTHOR="$VALUE"
|
|
;;
|
|
default_handle)
|
|
AUTHOR_DEFAULT_HANDLE="$VALUE"
|
|
;;
|
|
author_handle)
|
|
if [[ $AUTHOR_HANDLE != "$VALUE" ]]; then
|
|
echo "$0: ERROR: AUTHOR_HANDLE: $AUTHOR_HANDLE != author_handle value: $VALUE" 1>&2
|
|
exit 22
|
|
fi
|
|
AUTHOR_INFO[author_handle]="$VALUE"
|
|
;;
|
|
author_number)
|
|
if [[ $i != "$VALUE" ]]; then
|
|
echo "$0: ERROR: AUTHOR_HANDLE: $AUTHOR_HANDLE i: $i != author_number: $VALUE" 1>&2
|
|
exit 23
|
|
fi
|
|
AUTHOR_AUTHOR_NUMBER="$VALUE"
|
|
;;
|
|
*)
|
|
echo "$0: ERROR: AUTHOR_HANDLE: $AUTHOR_HANDLE unknown name: $NAME" 1>&2
|
|
exit 24
|
|
;;
|
|
esac
|
|
done <<< "$AUTHOR_DATA"
|
|
|
|
# verify we have all of the required information for this particular author
|
|
#
|
|
for NAME in name location_code email url alt_url mastodon github affiliation author_handle; do
|
|
if [[ -z ${AUTHOR_INFO[${NAME}]} ]]; then
|
|
echo "$0: ERROR: AUTHOR_HANDLE[$i]: $AUTHOR_HANDLE missing $NAME value from: $AUTH_JSON" 1>&2
|
|
exit 25
|
|
fi
|
|
done
|
|
if [[ -z $AUTHOR_PAST_WINNING_AUTHOR ]]; then
|
|
echo "$0: ERROR: AUTHOR_HANDLE[$i]: $AUTHOR_HANDLE missing past_winning_author value from: $AUTH_JSON" 1>&2
|
|
exit 26
|
|
fi
|
|
if [[ -z $AUTHOR_DEFAULT_HANDLE ]]; then
|
|
echo "$0: ERROR: AUTHOR_HANDLE[$i]: $AUTHOR_HANDLE missing default_handle value from: $AUTH_JSON" 1>&2
|
|
exit 27
|
|
fi
|
|
if [[ -z $AUTHOR_AUTHOR_NUMBER ]]; then
|
|
echo "$0: ERROR: AUTHOR_HANDLE[$i]: $AUTHOR_HANDLE missing author_number value from: $AUTH_JSON" 1>&2
|
|
exit 28
|
|
fi
|
|
|
|
# determine sort_word from the Author's last name
|
|
#
|
|
SORT_WORD=$(echo "${AUTHOR_INFO[name]}" | sed -e 's/^.* //' | tr '[:upper:]' '[:lower:]' | tr -d -c 'a-z0-9')
|
|
export SORT_WORD
|
|
if [[ -z $SORT_WORD ]]; then
|
|
echo "$0: ERROR: AUTHOR_HANDLE: $AUTHOR_HANDLE unable to determine the sort_word for: ${AUTHOR_INFO[name]}" 1>&2
|
|
exit 29
|
|
fi
|
|
case "$SORT_WORD" in
|
|
[a-z]*) ;;
|
|
*) SORT_WORD="z$SORT_WORD" ;; # prepend if the last name does not begin with a letter
|
|
esac
|
|
AUTHOR_INFO[sort_word]="$SORT_WORD"
|
|
|
|
# determine the mastodon_url for non-null mastodon
|
|
#
|
|
case "${AUTHOR_INFO[mastodon]}" in
|
|
\"@*@*\")
|
|
# We have a 2 phase swap and substitution. As such it is simpler to use sed.
|
|
#
|
|
# SC2001 (style): See if you can use ${variable//search/replace} instead.
|
|
# https://www.shellcheck.net/wiki/SC2001
|
|
# shellcheck disable=SC2001
|
|
AUTHOR_INFO[mastodon_url]=$(echo "${AUTHOR_INFO[mastodon]}" |
|
|
sed -e 's;^"@\([^@]*\)@\(.*\)"$;https://\2/\1;') ;;
|
|
*) AUTHOR_INFO[mastodon_url]="null" ;;
|
|
esac
|
|
|
|
# form author/author_handle.json
|
|
#
|
|
AUTHOR_HANDLE_JSON="author/$AUTHOR_HANDLE.json"
|
|
|
|
# clear the entry_id set
|
|
#
|
|
unset ENTRY_ID_SET
|
|
declare -ag ENTRY_ID_SET
|
|
|
|
# case: author/author_handle.json exists
|
|
#
|
|
if [[ -e $AUTHOR_HANDLE_JSON ]]; then
|
|
|
|
# firewall
|
|
#
|
|
if [[ ! -f $AUTHOR_HANDLE_JSON ]]; then
|
|
echo "$0: ERROR: author_handle JSON is not a file: $AUTHOR_HANDLE_JSON" 1>&2
|
|
exit 30
|
|
fi
|
|
if [[ ! -r $AUTHOR_HANDLE_JSON ]]; then
|
|
echo "$0: ERROR: author_handle JSON is not a readable file: $AUTHOR_HANDLE_JSON" 1>&2
|
|
exit 31
|
|
fi
|
|
if [[ ! -s $AUTHOR_HANDLE_JSON ]]; then
|
|
echo "$0: ERROR: author_handle JSON is not a non-empty readable file: $AUTHOR_HANDLE_JSON" 1>&2
|
|
exit 32
|
|
fi
|
|
|
|
# parse author/author_handle.json file other than the winning_entry_set
|
|
#
|
|
if [[ $V_FLAG -ge 5 ]]; then
|
|
echo "$0: debug[5]: about to run: $JVAL_WRAPPER -q -- $AUTHOR_HANDLE_JSON | sed -E -e ..." 1>&2
|
|
fi
|
|
export AUTHOR_DATA
|
|
AUTHOR_DATA=$("$JVAL_WRAPPER" -q -- "$AUTHOR_HANDLE_JSON" |
|
|
sed -E -e '/^entry_id\t/d')
|
|
status_codes=("${PIPESTATUS[@]}")
|
|
if [[ ${status_codes[*]} =~ [1-9] ]]; then
|
|
echo "$0: ERROR: $JVAL_WRAPPER -q -- $AUTHOR_HANDLE_JSON | sed -E -e ... failed," \
|
|
"error codes: ${status_codes[*]}" 1>&2
|
|
exit 33
|
|
fi
|
|
if [[ -z $AUTHOR_DATA ]]; then
|
|
echo "$0: ERROR: found entry_id's in: $AUTH_JSON" 1>&2
|
|
exit 34
|
|
fi
|
|
while read -r NAME VALUE; do
|
|
|
|
# parse name value got non
|
|
#
|
|
case "$NAME" in
|
|
no_comment)
|
|
if [[ $VALUE != "$NO_COMMENT" ]]; then
|
|
echo "$0: ERROR: author_handle file: $AUTHOR_HANDLE_JSON" \
|
|
"invalid no_comment: $VALUE != \"$NO_COMMENT\"" 1>&2
|
|
exit 35
|
|
fi
|
|
;;
|
|
author_JSON_format_version)
|
|
if [[ $VALUE != "$AUTHOR_JSON_FORMAT_VERSION" ]]; then
|
|
echo "$0: ERROR: author_handle file: $AUTHOR_HANDLE_JSON" \
|
|
"invalid author_JSON_format_version: $VALUE != \"$AUTHOR_JSON_FORMAT_VERSION\"" 1>&2
|
|
exit 36
|
|
fi
|
|
;;
|
|
author_handle)
|
|
if [[ $VALUE != "${AUTHOR_INFO[author_handle]}" ]]; then
|
|
echo "$0: ERROR: author_handle file: $AUTHOR_HANDLE_JSON" \
|
|
"invalid author_handle: $VALUE != ${AUTHOR_INFO[author_handle]}" 1>&2
|
|
exit 37
|
|
fi
|
|
;;
|
|
full_name)
|
|
if [[ $VALUE != "${AUTHOR_INFO[name]}" ]]; then
|
|
echo "$0: notice: author_handle file: $AUTHOR_HANDLE_JSON" \
|
|
"change of full_name from: $VALUE to: ${AUTHOR_INFO[name]}" 1>&2
|
|
echo 1>&2
|
|
fi
|
|
;;
|
|
sort_word)
|
|
if [[ $VALUE != "${AUTHOR_INFO[sort_word]}" ]]; then
|
|
echo "$0: notice: author_handle file: $AUTHOR_HANDLE_JSON" \
|
|
"change of sort_word from: $VALUE to: ${AUTHOR_INFO[sort_word]}" 1>&2
|
|
echo 1>&2
|
|
fi
|
|
;;
|
|
location_code)
|
|
if [[ $VALUE != "${AUTHOR_INFO[location_code]}" ]]; then
|
|
echo "$0: notice: author_handle file: $AUTHOR_HANDLE_JSON" \
|
|
"change of location_code from: $VALUE to: ${AUTHOR_INFO[location_code]}" 1>&2
|
|
echo 1>&2
|
|
fi
|
|
;;
|
|
email)
|
|
if [[ $VALUE != "${AUTHOR_INFO[email]}" ]]; then
|
|
echo "$0: notice: author_handle file: $AUTHOR_HANDLE_JSON" \
|
|
"change of email from: $VALUE to: ${AUTHOR_INFO[email]}" 1>&2
|
|
echo 1>&2
|
|
fi
|
|
;;
|
|
url)
|
|
if [[ $VALUE != "${AUTHOR_INFO[url]}" ]]; then
|
|
echo "$0: notice: author_handle file: $AUTHOR_HANDLE_JSON" \
|
|
"change of url from: $VALUE to: ${AUTHOR_INFO[url]}" 1>&2
|
|
echo 1>&2
|
|
fi
|
|
;;
|
|
alt_url)
|
|
if [[ $VALUE != "${AUTHOR_INFO[alt_url]}" ]]; then
|
|
echo "$0: notice: author_handle file: $AUTHOR_HANDLE_JSON" \
|
|
"change of alt_url from: $VALUE to: ${AUTHOR_INFO[alt_url]}" 1>&2
|
|
echo 1>&2
|
|
fi
|
|
;;
|
|
deprecated_twitter_handle)
|
|
AUTHOR_INFO[deprecated_twitter_handle]="$VALUE"
|
|
;;
|
|
mastodon)
|
|
if [[ $VALUE != "${AUTHOR_INFO[mastodon]}" ]]; then
|
|
echo "$0: notice: author_handle file: $AUTHOR_HANDLE_JSON" \
|
|
"change of mastodon from: $VALUE to: ${AUTHOR_INFO[mastodon]}" 1>&2
|
|
echo 1>&2
|
|
fi
|
|
;;
|
|
mastodon_url)
|
|
if [[ $VALUE != "${AUTHOR_INFO[mastodon_url]}" ]]; then
|
|
echo "$0: notice: author_handle file: $AUTHOR_HANDLE_JSON" \
|
|
"change of mastodon_url from: $VALUE to: ${AUTHOR_INFO[mastodon_url]}" 1>&2
|
|
echo 1>&2
|
|
fi
|
|
;;
|
|
github)
|
|
if [[ $VALUE != "${AUTHOR_INFO[github]}" ]]; then
|
|
echo "$0: notice: author_handle file: $AUTHOR_HANDLE_JSON" \
|
|
"change of github from: $VALUE to: ${AUTHOR_INFO[github]}" 1>&2
|
|
echo 1>&2
|
|
fi
|
|
;;
|
|
affiliation)
|
|
if [[ $VALUE != "${AUTHOR_INFO[affiliation]}" ]]; then
|
|
echo "$0: notice: author_handle file: $AUTHOR_HANDLE_JSON" \
|
|
"change of affiliation from: $VALUE to: ${AUTHOR_INFO[affiliation]}" 1>&2
|
|
echo 1>&2
|
|
fi
|
|
;;
|
|
*)
|
|
echo "$0: ERROR: author_handle file: $AUTHOR_HANDLE_JSON" \
|
|
"unknown $NAME : $VALUE" 1>&2
|
|
exit 38
|
|
;;
|
|
esac
|
|
done <<< "$AUTHOR_DATA"
|
|
|
|
# collect the entry_ids from the winning_entry_set and add the new entry_id
|
|
#
|
|
PATTERN='$..entry_id'
|
|
if [[ $V_FLAG -ge 5 ]]; then
|
|
echo "$0: debug[5]: about to run: $JVAL_WRAPPER -b -q -- $AUTHOR_HANDLE_JSON '$PATTERN'" 1>&2
|
|
fi
|
|
export ENTRY_IDS
|
|
ENTRY_IDS=$( { "$JVAL_WRAPPER" -b -q -- "$AUTHOR_HANDLE_JSON" "$PATTERN";
|
|
status="$?"
|
|
if [[ $status -ne 0 ]]; then
|
|
echo "$0: ERROR: $JVAL_WRAPPER -b -q -- $AUTHOR_HANDLE_JSON '$PATTERN' failed," \
|
|
"error code: $status" 1>&2
|
|
exit 39
|
|
fi
|
|
echo "$ENTRY_ID"
|
|
} | LC_ALL=C sort -d -u )
|
|
if [[ -z $AUTHOR_DATA ]]; then
|
|
echo "$0: ERROR: found no entry_id's in: $AUTHOR_HANDLE_JSON" 1>&2
|
|
exit 40
|
|
fi
|
|
while read -r ENTRY_ID_SET_VALUE; do
|
|
ENTRY_ID_SET+=("$ENTRY_ID_SET_VALUE")
|
|
done <<< "$ENTRY_IDS"
|
|
|
|
# case: a new author/author_handle.json needs to be formed
|
|
#
|
|
else
|
|
ENTRY_ID_SET+=("$ENTRY_ID")
|
|
fi
|
|
|
|
# create or modify the author/author_handle.json as needed
|
|
#
|
|
write_author_handle_file AUTHOR_INFO ENTRY_ID_SET "$TMP_AUTHOR_HANDLE_JSON" "$AUTHOR_HANDLE_JSON"
|
|
status="$?"
|
|
if [[ $status -ne 0 ]]; then
|
|
echo "$0: ERROR: write_author_handle_file AUTHOR_INFO ENTRY_ID_SET" \
|
|
"$TMP_AUTHOR_HANDLE_JSON $AUTHOR_HANDLE_JSON failed," \
|
|
"error code: $status" 1>&2
|
|
exit 41
|
|
fi
|
|
|
|
# output the author_handle information for .entry.json
|
|
#
|
|
printf " {\n"
|
|
printf " \"author_handle\" : \"%s\"\n" "$AUTHOR_HANDLE"
|
|
printf " }"
|
|
|
|
# count this author
|
|
#
|
|
((++i))
|
|
done >> "$TMP_ENTRY_JSON"
|
|
printf "\n ],\n" >> "$TMP_ENTRY_JSON"
|
|
|
|
# begin the manifest array
|
|
#
|
|
echo " \"manifest\" : [" >> "$TMP_ENTRY_JSON"
|
|
((count=0))
|
|
|
|
# write manifest csv line for entry source code
|
|
#
|
|
# This is the 1st manifest element of the array. Moreover, we will
|
|
# leave out the trailing comma.
|
|
#
|
|
((++count))
|
|
PATTERN='$..c_src'
|
|
if [[ $V_FLAG -ge 5 ]]; then
|
|
echo "$0: debug[5]: about to run: $JVAL_WRAPPER -b -q -- $INFO_JSON '$PATTERN'" 1>&2
|
|
fi
|
|
export FILE_PATH
|
|
FILE_PATH=$("$JVAL_WRAPPER" -b -q -- "$INFO_JSON" "$PATTERN")
|
|
status="$?"
|
|
if [[ $status -ne 0 ]]; then
|
|
echo "$0: ERROR: $JVAL_WRAPPER -b -q -- $INFO_JSON '$PATTERN' failed," \
|
|
"error code: $status" 1>&2
|
|
exit 42
|
|
fi
|
|
if [[ -z $FILE_PATH ]]; then
|
|
echo "$0: ERROR: cannot determine c_src in manifest from: $INFO_JSON" 1>&2
|
|
exit 7
|
|
fi
|
|
if [[ ! -e $YYYY_DIR/$FILE_PATH ]]; then
|
|
echo "$0: ERROR: manifest file for c_src does not exist: $YYYY_DIR/$FILE_PATH" 1>&2
|
|
exit 43
|
|
fi
|
|
if [[ ! -f $YYYY_DIR/$FILE_PATH ]]; then
|
|
echo "$0: ERROR: manifest file for c_src is not a file: $YYYY_DIR/$FILE_PATH" 1>&2
|
|
exit 44
|
|
fi
|
|
manifest_csv "$FILE_PATH" 20 true c true "entry source code" >> "$TMP_MANIFEST_CSV"
|
|
export PROG_C="$FILE_PATH"
|
|
|
|
# write manifest csv line for entry Makefile
|
|
#
|
|
((++count))
|
|
PATTERN='$..Makefile'
|
|
if [[ $V_FLAG -ge 5 ]]; then
|
|
echo "$0: debug[5]: about to run: $JVAL_WRAPPER -b -q -- $INFO_JSON '$PATTERN'" 1>&2
|
|
fi
|
|
export FILE_PATH
|
|
FILE_PATH=$("$JVAL_WRAPPER" -b -q -- "$INFO_JSON" "$PATTERN")
|
|
status="$?"
|
|
if [[ $status -ne 0 ]]; then
|
|
echo "$0: ERROR: $JVAL_WRAPPER -b -q -- $INFO_JSON '$PATTERN' failed," \
|
|
"error code: $status" 1>&2
|
|
exit 45
|
|
fi
|
|
if [[ -z $FILE_PATH ]]; then
|
|
echo "$0: ERROR: cannot determine Makefile in manifest from: $INFO_JSON" 1>&2
|
|
exit 46
|
|
fi
|
|
if [[ ! -e $YYYY_DIR/$FILE_PATH ]]; then
|
|
echo "$0: ERROR: manifest file for Makefile does not exist: $YYYY_DIR/$FILE_PATH" 1>&2
|
|
exit 47
|
|
fi
|
|
if [[ ! -f $YYYY_DIR/$FILE_PATH ]]; then
|
|
echo "$0: ERROR: manifest file for Makefile is not a file: $YYYY_DIR/$FILE_PATH" 1>&2
|
|
exit 48
|
|
fi
|
|
manifest_csv "$FILE_PATH" 30 true makefile true "entry Makefile" >> "$TMP_MANIFEST_CSV"
|
|
|
|
# write manifest csv line for alt source file if found
|
|
#
|
|
export ALT_C
|
|
ALT_C=$(basename "$PROG_C" .c)".alt.c"
|
|
if [[ -f $YYYY_DIR/$ALT_C ]]; then
|
|
|
|
# manifest for entry alt source code
|
|
#
|
|
((++count))
|
|
manifest_csv "$ALT_C" 40 true c true "alternate source code" >> "$TMP_MANIFEST_CSV"
|
|
fi
|
|
|
|
# form original source code if needed
|
|
#
|
|
export ORIG_C
|
|
ORIG_C=$(basename "$PROG_C" .c)".orig.c"
|
|
if [[ ! -f $YYYY_DIR/$ORIG_C ]]; then
|
|
if [[ $V_FLAG -ge 3 ]]; then
|
|
echo "$0: debug[3]: about to run: cp -f -p -v $YYYY_DIR/$PROG_C $YYYY_DIR/$ORIG_C" 1>&2
|
|
cp -f -p -v "$YYYY_DIR/$PROG_C" "$YYYY_DIR/$ORIG_C"
|
|
status="$?"
|
|
if [[ $status -ne 0 ]]; then
|
|
echo "$0: ERROR: cp -f -p -v $YYYY_DIR/$PROG_C $YYYY_DIR/$ORIG_C failed," \
|
|
"error code: $status" 1>&2
|
|
exit 49
|
|
fi
|
|
else
|
|
cp -f -p "$YYYY_DIR/$PROG_C" "$YYYY_DIR/$ORIG_C"
|
|
status="$?"
|
|
if [[ $status -ne 0 ]]; then
|
|
echo "$0: ERROR: cp -f -p $YYYY_DIR/$PROG_C $YYYY_DIR/$ORIG_C failed," \
|
|
"error code: $status" 1>&2
|
|
exit 50
|
|
fi
|
|
fi
|
|
fi
|
|
|
|
# write manifest csv line for original source code
|
|
#
|
|
((++count))
|
|
manifest_csv "$ORIG_C" 50 false c true "original source code" >> "$TMP_MANIFEST_CSV"
|
|
|
|
# collect manifest for extra_file(s)
|
|
#
|
|
export PATTERN
|
|
PATTERN='$..extra_file'
|
|
if [[ $V_FLAG -ge 5 ]]; then
|
|
echo "$0: debug[5]: about to run: $JVAL_WRAPPER -b -q -- $INFO_JSON '$PATTERN' | ,,, sort ..." 1>&2
|
|
fi
|
|
export EXTRA_FILE_SET
|
|
EXTRA_FILE_SET=$("$JVAL_WRAPPER" -b -q -- "$INFO_JSON" "$PATTERN" | LC_ALL=C sort -d -u)
|
|
status_codes=("${PIPESTATUS[@]}")
|
|
if [[ ${status_codes[*]} =~ [1-9] ]]; then
|
|
echo "$0: ERROR: $JVAL_WRAPPER -b -q -- $INFO_JSON '$PATTERN' | ... sort ... failed," \
|
|
"error code: ${status_codes[*]}" 1>&2
|
|
exit 51
|
|
fi
|
|
|
|
# if try.sh does not exist, copy example over, otherwise just update the manifest
|
|
#
|
|
if [[ ! -f $TRY_SH ]]; then
|
|
if [[ $V_FLAG -ge 3 ]]; then
|
|
echo "$0: debug[3]: about to run: cp -f -p -v $TEMPLATE_TRY_SH $TRY_SH" 1>&2
|
|
cp -f -p -v "$TEMPLATE_TRY_SH" "$TRY_SH"
|
|
status="$?"
|
|
if [[ $status -ne 0 ]]; then
|
|
echo "$0: ERROR: cp -f -p -v $TEMPLATE_TRY_SH $TRY_SH failed," \
|
|
"error code: $status" 1>&2
|
|
exit 52
|
|
fi
|
|
else
|
|
cp -f -p "$TEMPLATE_TRY_SH" "$TRY_SH"
|
|
status="$?"
|
|
if [[ $status -ne 0 ]]; then
|
|
echo "$0: ERROR: cp -f -p $TEMPLATE_TRY_SH $TRY_SH failed," \
|
|
"error code: $status" 1>&2
|
|
exit 53
|
|
fi
|
|
fi
|
|
fi
|
|
|
|
# write manifest csv line for try.sh
|
|
#
|
|
((++count))
|
|
manifest_csv try.sh 100 true shellscript true "script to try entry" \
|
|
>> "$TMP_MANIFEST_CSV"
|
|
|
|
# write manifest csv line for try.alt.sh if it exists
|
|
#
|
|
if [[ -f $TRY_ALT_SH ]]; then
|
|
((++count))
|
|
manifest_csv try.alt.sh 100 true shellscript true "script to try alternate code" \
|
|
>> "$TMP_MANIFEST_CSV"
|
|
fi
|
|
|
|
# perform some validation checks on the extra_file set
|
|
#
|
|
for EXTRA_FILE in $EXTRA_FILE_SET; do
|
|
|
|
# test if extra_file is an invalid filename
|
|
#
|
|
case "$EXTRA_FILE" in
|
|
prog.c|Makefile|prog.orig.c|index.html|README.md|remarks.md|\.*)
|
|
echo "$0: ERROR: invalid extra_file filename: $EXTRA_FILE" 1>&2
|
|
exit 54
|
|
;;
|
|
*) ;;
|
|
esac
|
|
|
|
# test if extra_file is not a file
|
|
#
|
|
if [[ ! -e $YYYY_DIR/$EXTRA_FILE ]]; then
|
|
echo "$0: ERROR: manifest file for extra_file does not exist: $YYYY_DIR/$EXTRA_FILE" 1>&2
|
|
exit 55
|
|
fi
|
|
if [[ ! -f $YYYY_DIR/$EXTRA_FILE ]]; then
|
|
echo "$0: ERROR: manifest file for extra_file is not a file: $YYYY_DIR/$EXTRA_FILE" 1>&2
|
|
exit 56
|
|
fi
|
|
done
|
|
|
|
# process HTML files that do not yet exist but are associated with markdown extra_files
|
|
#
|
|
for EXTRA_FILE in $EXTRA_FILE_SET; do
|
|
|
|
# case: extra_file is a markdown file
|
|
#
|
|
if [[ $EXTRA_FILE =~ (.*)\.md$ ]]; then
|
|
|
|
# warn if there is a HTML file associated with the markdown file
|
|
#
|
|
export HTML_FILE="${BASH_REMATCH[1]}.html"
|
|
if [[ -e $YYYY_DIR/$HTML_FILE ]]; then
|
|
echo 1>&2
|
|
echo "$0: Warning: markdown file: $EXTRA_FILE and HTML file: $HTML_FILE both exist" 1>&2
|
|
echo "$0: Warning: verify HTML file is an HTML version of markdown," \
|
|
"or exclude $YYYY_DIR/$EXTRA_FILE from bin/md2html.cfg processing" 1>&2
|
|
echo 1>&2
|
|
fi
|
|
HTML_FILE_BASENAME=$(basename "$HTML_FILE")
|
|
export HTML_FILE_BASENAME
|
|
|
|
# write manifest csv line for the markdown file
|
|
#
|
|
((++count))
|
|
manifest_csv "$EXTRA_FILE" 4000000000 true markdown true \
|
|
"markdown source for $HTML_FILE_BASENAME" >> "$TMP_MANIFEST_CSV"
|
|
|
|
# prompt for entry_text of HTML file
|
|
#
|
|
VALUE=
|
|
prompt_string "entry_text for $HTML_FILE"
|
|
status="$?"
|
|
if [[ $status -ne 0 || -z $VALUE ]]; then
|
|
echo "$0: ERROR: prompt_string entry_text for $HTML_FILE failed," \
|
|
"error code: $status" 1>&2
|
|
exit 1
|
|
fi
|
|
export ENTRY_TEXT="$VALUE"
|
|
|
|
# write manifest csv line for the HTML file associated with the markdown file
|
|
#
|
|
((++count))
|
|
manifest_csv "$HTML_FILE" 100 false markdown true "$ENTRY_TEXT" >> "$TMP_MANIFEST_CSV"
|
|
|
|
# case: extra_file is an HTML file
|
|
#
|
|
elif [[ $EXTRA_FILE =~ (.*)\.html$ ]]; then
|
|
|
|
# case: there is a markdown file associated with this HTML file
|
|
#
|
|
export MD_FILE="${BASH_REMATCH[1]}.md"
|
|
if [[ -e $YYYY_DIR/$HTML_FILE ]]; then
|
|
|
|
# NOTE: We have or will process the HTML file in this loop, nothing to do here
|
|
#
|
|
continue
|
|
fi
|
|
|
|
# prompt for entry_text of HTML file
|
|
#
|
|
VALUE=
|
|
prompt_string "entry_text for $EXTRA_FILE"
|
|
status="$?"
|
|
if [[ $status -ne 0 || -z $VALUE ]]; then
|
|
echo "$0: ERROR: prompt_string inventory_order for $EXTRA_FILE failed," \
|
|
"error code: $status" 1>&2
|
|
exit 1
|
|
fi
|
|
export ENTRY_TEXT="$VALUE"
|
|
|
|
# write manifest csv line for the HTML file associated with the markdown file
|
|
#
|
|
((++count))
|
|
manifest_csv "$EXTRA_FILE" 100 false html true "$ENTRY_TEXT" >> "$TMP_MANIFEST_CSV"
|
|
fi
|
|
done
|
|
|
|
# process extra_files that are neither markdown nor HTML
|
|
#
|
|
export BASENAME_TRY_SH
|
|
BASENAME_TRY_SH=$(basename "$TRY_SH")
|
|
export BASENAME_TRY_ALT_SH
|
|
BASENAME_TRY_ALT_SH=$(basename "$TRY_ALT_SH")
|
|
for EXTRA_FILE in $EXTRA_FILE_SET; do
|
|
|
|
# ignore HTML files because we processed them above
|
|
#
|
|
if [[ $EXTRA_FILE =~ \.html$ || $EXTRA_FILE =~ \.md$ ]]; then
|
|
continue
|
|
fi
|
|
|
|
# ignore prog.alt.c because we processed it above
|
|
#
|
|
if [[ $EXTRA_FILE == "$ALT_C" ]]; then
|
|
continue
|
|
fi
|
|
|
|
# ignore try.sh because we processed it above
|
|
#
|
|
if [[ $EXTRA_FILE == "$BASENAME_TRY_SH" ]]; then
|
|
continue
|
|
fi
|
|
|
|
# ignore try.alt.sh because we processed it above
|
|
#
|
|
if [[ $EXTRA_FILE == "$BASENAME_TRY_ALT_SH" ]]; then
|
|
continue
|
|
fi
|
|
|
|
# prompt for inventory_order
|
|
#
|
|
VALUE=
|
|
prompt_integer "inventory_order for $EXTRA_FILE"
|
|
status="$?"
|
|
if [[ $status -ne 0 || -z $VALUE ]]; then
|
|
echo "$0: ERROR: prompt_integer inventory_order for $EXTRA_FILE failed," \
|
|
"error code: $status" 1>&2
|
|
exit 1
|
|
fi
|
|
export INVENTORY_ORDER="$VALUE"
|
|
|
|
# prompt for display_as
|
|
#
|
|
VALUE=
|
|
prompt_word "display_as for $EXTRA_FILE"
|
|
status="$?"
|
|
if [[ $status -ne 0 || -z $VALUE ]]; then
|
|
echo "$0: ERROR: prompt_word display_as for $EXTRA_FILE failed," \
|
|
"error code: $status" 1>&2
|
|
exit 1
|
|
fi
|
|
export DISPLAY_AS="$VALUE"
|
|
|
|
# prompt for entry_text
|
|
#
|
|
VALUE=
|
|
prompt_string "entry_text for $EXTRA_FILE"
|
|
status="$?"
|
|
if [[ $status -ne 0 || -z $VALUE ]]; then
|
|
echo "$0: ERROR: prompt_string entry_text for $EXTRA_FILE failed," \
|
|
"error code: $status" 1>&2
|
|
exit 1
|
|
fi
|
|
export ENTRY_TEXT="$VALUE"
|
|
|
|
# write manifest csv line for original source code
|
|
#
|
|
((++count))
|
|
manifest_csv "$EXTRA_FILE" "$INVENTORY_ORDER" true "$DISPLAY_AS" true "$ENTRY_TEXT" >> "$TMP_MANIFEST_CSV"
|
|
done
|
|
|
|
# write manifest csv line for compressed tarball
|
|
#
|
|
((++count))
|
|
manifest_csv "$ENTRY_ID.tar.bz2" 1415926535 false tbz2 false "download entry tarball" >> "$TMP_MANIFEST_CSV"
|
|
|
|
# write manifest csv line for .entry.json
|
|
#
|
|
((++count))
|
|
manifest_csv .entry.json 4000000000 true json true "entry summary and manifest in JSON" >> "$TMP_MANIFEST_CSV"
|
|
|
|
# form .gitignore if needed
|
|
#
|
|
if [[ ! -f $DOT_GITIGNORE ]]; then
|
|
if [[ $V_FLAG -ge 3 ]]; then
|
|
echo "$0: debug[3]: about to run: cp -f -p -v $TEMPLATE_GITIGNORE $DOT_GITIGNORE" 1>&2
|
|
cp -f -p -v "$YYYY_DIR/$DOT_GITIGNORE" "$DOT_GITIGNORE"
|
|
status="$?"
|
|
if [[ $status -ne 0 ]]; then
|
|
echo "$0: ERROR: cp -f -p -v $TEMPLATE_GITIGNORE $DOT_GITIGNORE failed," \
|
|
"error code: $status" 1>&2
|
|
exit 57
|
|
fi
|
|
else
|
|
cp -f -p "$TEMPLATE_GITIGNORE" "$DOT_GITIGNORE"
|
|
status="$?"
|
|
if [[ $status -ne 0 ]]; then
|
|
echo "$0: ERROR: cp -f -p $TEMPLATE_GITIGNORE $DOT_GITIGNORE failed," \
|
|
"error code: $status" 1>&2
|
|
exit 58
|
|
fi
|
|
fi
|
|
fi
|
|
|
|
# write manifest csv line for .gitignore
|
|
#
|
|
((++count))
|
|
manifest_csv .gitignore 4000000000 true gitignore true "list of files that should not be committed under git" \
|
|
>> "$TMP_MANIFEST_CSV"
|
|
|
|
# form .path if needed
|
|
#
|
|
if [[ ! -f $DOT_PATH ]]; then
|
|
echo "$YYYY_DIR" > "$DOT_PATH"
|
|
fi
|
|
|
|
# write manifest csv line for .path
|
|
#
|
|
((++count))
|
|
manifest_csv .path 4000000000 false path false "directory path from top level directory" \
|
|
>> "$TMP_MANIFEST_CSV"
|
|
|
|
# form README.md if needed
|
|
#
|
|
if [[ ! -f $README_MD ]]; then
|
|
|
|
if [[ $V_FLAG -ge 3 ]]; then
|
|
echo "$0: debug[3]: forming README.md: $README_MD"
|
|
fi
|
|
"$GEN_README_TOOL" "$YEAR_DIR" "$TEMPLATE_README_MD_HEAD" "$YYYY_DIR/remarks.md" "$TEMPLATE_README_MD_TAIL" "$README_MD"
|
|
status="$?"
|
|
if [[ $status -ne 0 ]]; then
|
|
echo "$0: ERROR: $GEN_README_TOOL $YEAR_DIR $TEMPLATE_README_MD_HEAD $YYYY_DIR/remarks.md" \
|
|
"$TEMPLATE_README_MD_TAIL $README_MD failed," \
|
|
"error code: $status" 1>&2
|
|
exit 59
|
|
fi
|
|
elif [[ $V_FLAG -ge 3 ]]; then
|
|
echo "$0: debug[3]: README.md file already exists, skipping forming: $README_MD" 1>&2
|
|
fi
|
|
|
|
# write manifest csv line for README.md
|
|
#
|
|
((++count))
|
|
manifest_csv README.md 4000000000 true markdown true "markdown source for this web page" \
|
|
>> "$TMP_MANIFEST_CSV"
|
|
|
|
# write manifest csv line for index.html
|
|
#
|
|
((++count))
|
|
manifest_csv index.html 4294967295 false html false "this web page" >> "$TMP_MANIFEST_CSV"
|
|
|
|
# sort the manifest csv file
|
|
#
|
|
if [[ $V_FLAG -ge 5 ]]; then
|
|
echo "$0: debug[5]: about to: LC_ALL=C sort -t, -k2n -k1,1 -k3,6 $TMP_MANIFEST_CSV -o $TMP_MANIFEST_CSV" 1>&2
|
|
fi
|
|
LC_ALL=C sort -t, -k2n -k1,1 -k3,6 "$TMP_MANIFEST_CSV" -o "$TMP_MANIFEST_CSV"
|
|
status="$?"
|
|
if [[ $status -ne 0 ]]; then
|
|
echo "$0: ERROR: LC_ALL=C sort -t, -k2n -k1,1 -k3,6 $TMP_MANIFEST_CSV -o $TMP_MANIFEST_CSV failed," \
|
|
"error code: $status" 1>&2
|
|
exit 60
|
|
elif [[ $V_FLAG -ge 3 ]]; then
|
|
echo "$0: debug[3]: sorted temporary manifest csv file: $TMP_MANIFEST_CSV" 1>&2
|
|
fi
|
|
|
|
# convert manifest csv lines in the manifest csv file into manifest JSON entries
|
|
#
|
|
MANIFEST_CSV_LINES=$(wc -l < "$TMP_MANIFEST_CSV")
|
|
export MANIFEST_CSV_LINES
|
|
export line=0
|
|
sed -e 's/,/ /g' "$TMP_MANIFEST_CSV" |
|
|
while read -r FILE_PATH INVENTORY_ORDER OK_TO_EDIT DISPLAY_AS DISPLAY_VIA_GITHUB ENTRY_TEXT; do
|
|
|
|
# determine if manifest needs a comma
|
|
#
|
|
((++line))
|
|
export COMMA="comma"
|
|
if [[ $line -ge $MANIFEST_CSV_LINES ]]; then
|
|
COMMA=""
|
|
fi
|
|
|
|
# write inventory item into temporary .entry.json file
|
|
#
|
|
manifest_entry "$FILE_PATH" "$INVENTORY_ORDER" "$OK_TO_EDIT" "$DISPLAY_AS" "$DISPLAY_VIA_GITHUB" \
|
|
"$ENTRY_TEXT" "$COMMA" >> "$TMP_ENTRY_JSON"
|
|
done
|
|
|
|
# end the manifest array and end of temporary .entry.json file
|
|
#
|
|
# We complete the last manifest_entry that was written.
|
|
#
|
|
printf " ]\n}\n" >> "$TMP_ENTRY_JSON"
|
|
|
|
# validate the JSON in the temporary .entry.json file
|
|
#
|
|
if [[ $V_FLAG -ge 3 ]]; then
|
|
echo "$0: debug[3]: about to: $JPARSE_TOOL -q -- $TMP_ENTRY_JSON" 1>&2
|
|
fi
|
|
"$JPARSE_TOOL" -q -- "$TMP_ENTRY_JSON" 1>&2
|
|
status="$?"
|
|
if [[ $status -ne 0 ]]; then
|
|
echo "$0: ERROR: $JPARSE_TOOL -q -- $TMP_ENTRY_JSON filed," \
|
|
"error code: $status" 1>&2
|
|
exit 61
|
|
elif [[ $V_FLAG -ge 3 ]]; then
|
|
echo "$0: debug[3]: valid JSON: $TMP_ENTRY_JSON" 1>&2
|
|
fi
|
|
|
|
# update .entry.json if needed
|
|
#
|
|
if cmp -s "$TMP_ENTRY_JSON" "$ENTRY_JSON"; then
|
|
|
|
# case: .entry.json did not change
|
|
#
|
|
if [[ $V_FLAG -ge 5 ]]; then
|
|
echo "$0: debug[5]: .entry.json file did not change: $ENTRY_JSON" 1>&2
|
|
fi
|
|
|
|
else
|
|
|
|
# case: .entry.json file changed, update the file
|
|
#
|
|
if [[ $V_FLAG -ge 5 ]]; then
|
|
echo "$0: debug[5]: about to: mv -f -- $TMP_ENTRY_JSON $ENTRY_JSON" 1>&2
|
|
fi
|
|
if [[ $V_FLAG -ge 3 ]]; then
|
|
mv -f -v -- "$TMP_ENTRY_JSON" "$ENTRY_JSON" 1>&2
|
|
status="$?"
|
|
else
|
|
mv -f -- "$TMP_ENTRY_JSON" "$ENTRY_JSON" 1>&2
|
|
status="$?"
|
|
fi
|
|
if [[ $status -ne 0 ]]; then
|
|
echo "$0: ERROR: mv -f -- $TMP_ENTRY_JSON $ENTRY_JSON filed," \
|
|
"error code: $status" 1>&2
|
|
exit 62
|
|
elif [[ $V_FLAG -ge 1 ]]; then
|
|
echo "$0: debug[1]: updated .entry.json: $ENTRY_JSON" 1>&2
|
|
fi
|
|
if [[ ! -s $ENTRY_JSON ]]; then
|
|
echo "$0: ERROR: not a non-empty .entry.json: $ENTRY_JSON" 1>&2
|
|
exit 63
|
|
fi
|
|
fi
|
|
|
|
# case: with -n
|
|
#
|
|
elif [[ $V_FLAG -ge 3 ]]; then
|
|
echo "$0: debug[3]: -n disabled adding YYYY_DIR: $YYYY_DIR to $DOT_YEAR" 1>&2
|
|
fi
|
|
|
|
|
|
# build HTML files based on extra_file markdown files
|
|
#
|
|
for EXTRA_FILE in $EXTRA_FILE_SET; do
|
|
|
|
# case: extra_file is a markdown file
|
|
#
|
|
if [[ $EXTRA_FILE =~ (.*)\.md$ ]]; then
|
|
|
|
# form HTML file if it does not exist
|
|
#
|
|
export HTML_FILE="${BASH_REMATCH[1]}.html"
|
|
if [[ ! -e $HTML_FILE ]]; then
|
|
|
|
if [[ -z $NOOP ]]; then
|
|
|
|
if [[ $V_FLAG -ge 1 ]]; then
|
|
echo "$0: debug[1]: about to run: $OTHERMD2HTML_SH -v $V_FLAG -- $YYYY_DIR/$EXTRA_FILE" 1>&2
|
|
fi
|
|
"$OTHERMD2HTML_SH" -v "$V_FLAG" -- "$YYYY_DIR/$EXTRA_FILE"
|
|
status="$?"
|
|
if [[ $status -ne 0 ]]; then
|
|
echo "$0: ERROR: $OTHERMD2HTML_SH -v $V_FLAG -- $YYYY_DIR/$EXTRA_FILE filed," \
|
|
"error code: $status" 1>&2
|
|
exit 64
|
|
fi
|
|
elif [[ $V_FLAG -ge 3 ]]; then
|
|
echo "$0: debug[3]: -n disabled forming HTML: $YYYY_DIR/$HTML_FILE" 1>&2
|
|
fi
|
|
|
|
# HTML file already exists
|
|
#
|
|
elif [[ $V_FLAG -ge 1 ]]; then
|
|
echo "$0: notice: markdown: $YYYY_DIR/$EXTRA_FILE HTML file exists: $YYYY_DIR/$HTML_FILE" 1>&2
|
|
fi
|
|
fi
|
|
done
|
|
|
|
|
|
# verify that YYYY_DIR is in .allyear
|
|
#
|
|
# We need to be sure that YYYY_DIR is in .allyear as tools such as bin/subst.entry-navbar.awk
|
|
# use the contents of that file to generate the navigation bar in the index.html web page.
|
|
#
|
|
grep -q "^$YYYY_DIR$" "$ALLYEAR" >/dev/null 2>&1
|
|
status="$?"
|
|
if [[ $status -ne 0 ]]; then
|
|
|
|
if [[ -z $NOOP ]]; then
|
|
|
|
# make .allyear writable
|
|
#
|
|
chmod +w "$ALLYEAR"
|
|
status="$?"
|
|
if [[ $status -ne 0 ]]; then
|
|
echo "$0: ERROR: chmod +w $ALLYEAR filed," \
|
|
"error code: $status" 1>&2
|
|
exit 65
|
|
fi
|
|
|
|
# append YYYY_DIR to .allyear
|
|
#
|
|
echo "$YYYY_DIR" >> "$ALLYEAR"
|
|
|
|
# sort .allyear
|
|
#
|
|
sort -f -d -u "$ALLYEAR" -o "$ALLYEAR"
|
|
status="$?"
|
|
if [[ $status -ne 0 ]]; then
|
|
echo "$0: ERROR: sort -f -d -u $ALLYEAR -o $ALLYEAR filed," \
|
|
"error code: $status" 1>&2
|
|
exit 66
|
|
fi
|
|
|
|
elif [[ $V_FLAG -ge 1 ]]; then
|
|
echo "$0: debug[3]: -n disabled adding YYYY_DIR: $YYYY_DIR to .allyear: $ALLYEAR" 1>&2
|
|
fi
|
|
|
|
elif [[ $V_FLAG -ge 3 ]]; then
|
|
echo "$0: debug[3]: YYYY_DIR: $YYYY_DIR is already in .allyear: $ALLYEAR" 1>&2
|
|
fi
|
|
|
|
|
|
# form index.html if needed
|
|
#
|
|
if [[ -z $NOOP ]]; then
|
|
if [[ ! -f $INDEX_HTML ]]; then
|
|
|
|
if [[ $V_FLAG -ge 1 ]]; then
|
|
echo "$0: debug[1]: about to run: $MD2HTML_SH -v $V_FLAG -- $README_MD $INDEX_HTML" 1>&2
|
|
fi
|
|
"$MD2HTML_SH" -v "$V_FLAG" -- "$README_MD" "$INDEX_HTML"
|
|
status="$?"
|
|
if [[ $status -ne 0 ]]; then
|
|
echo "$0: ERROR: $MD2HTML_SH -v $V_FLAG -- $README_MD $INDEX_HTML filed," \
|
|
"error code: $status" 1>&2
|
|
exit 67
|
|
fi
|
|
fi
|
|
|
|
# case: with -n
|
|
#
|
|
elif [[ $V_FLAG -ge 3 ]]; then
|
|
echo "$0: debug[3]: -n disabled forming index.html: $INDEX_HTML" 1>&2
|
|
fi
|
|
|
|
|
|
# remove submission files that are no longer needed for a winning IOCCC entry
|
|
#
|
|
if [[ -z $NOOP ]]; then
|
|
|
|
if [[ $V_FLAG -ge 1 ]]; then
|
|
echo "$0: debug[1]: about to run: rm -f -v -- $INFO_JSON $AUTH_JSON $AUTH_JSON.xz $REMARKS_MD $YYYY_DIR/.prev" \
|
|
"$YYYY_DIR/.submit.sh $YYYY_DIR/.txz $YYYY_DIR/.num.sh $YYYY_DIR/.orig" 1>&2
|
|
fi
|
|
rm -f -v -- "$INFO_JSON" "$AUTH_JSON" "$AUTH_JSON.xz" "$REMARKS_MD" "$YYYY_DIR/.prev" \
|
|
"$YYYY_DIR/.submit.sh" "$YYYY_DIR/.txz" "$YYYY_DIR/.num.sh" "$YYYY_DIR/.orig"
|
|
status="$?"
|
|
if [[ $status -ne 0 ]]; then
|
|
echo "$0: ERROR: rm -f -v -- $INFO_JSON $AUTH_JSON $AUTH_JSON.xz $REMARKS_MD $YYYY_DIR/.prev" \
|
|
"$YYYY_DIR/.submit.sh $YYYY_DIR/.txz $YYYY_DIR/.num.sh $YYYY_DIR/.orig filed," \
|
|
"error code: $status" 1>&2
|
|
exit 68
|
|
fi
|
|
|
|
# case: with -n
|
|
#
|
|
elif [[ $V_FLAG -ge 3 ]]; then
|
|
echo "$0: debug[3]: -n disabled removal selective files under $YYYY_DIR" 1>&2
|
|
fi
|
|
|
|
|
|
# All Done!!! All Done!!! -- Jessica Noll, Age 2
|
|
#
|
|
exit 0
|