diff --git a/Makefile b/Makefile index d0b18b949..df1e9520f 100644 --- a/Makefile +++ b/Makefile @@ -66,6 +66,7 @@ TAR_YEAR= bin/tar-year.sh TAR_ALL= bin/tar-all.sh GEN_STATUS= bin/gen-status.sh GEN_SITEMAP= bin/gen-sitemap.sh +SORT_GITIGNORE= bin/sort.gitignore.sh ############# @@ -258,6 +259,7 @@ help: @echo make genpath @echo make genfilelist @echo make verify_entry_files + @echo make sort_gitignore @echo make gen_authors @echo make gen_location @echo make gen_years @@ -332,6 +334,12 @@ genfilelist: verify_entry_files: ${ALL_RUN} ${CHK_ENTRY} @echo '=-=-=-=-= IOCCC begin make $@ =-=-=-=-=' ${ALL_RUN} -v 3 ${CHK_ENTRY} + +# check to be sure all files in all entries exist +# +sort_gitignore: ${ALL_RUN} ${SORT_GITIGNORE} + @echo '=-=-=-=-= IOCCC begin make $@ =-=-=-=-=' + ${ALL_RUN} -v 3 ${SORT_GITIGNORE} -v 1 @echo '=-=-=-=-= IOCCC complete make $@ =-=-=-=-=' # generate the top level authors.html page using the @@ -421,6 +429,7 @@ quick_www: ${MAKE} genpath ${MAKE} genfilelist ${MAKE} verify_entry_files + ${MAKE} sort_gitignore ${MAKE} gen_authors ${MAKE} gen_location ${MAKE} gen_years @@ -440,6 +449,7 @@ www: ${MAKE} genpath ${MAKE} genfilelist ${MAKE} verify_entry_files + ${MAKE} sort_gitignore ${MAKE} gen_authors ${MAKE} gen_location ${MAKE} gen_years diff --git a/bin/README.md b/bin/README.md index 2d78fa3c6..ba78697ef 100644 --- a/bin/README.md +++ b/bin/README.md @@ -45,6 +45,12 @@ Or for example: bin/all-years.sh -v 1 bin/chk-entry.sh ``` +We recommend that this tool be invoked via the top level `Makefile`: + +```sh +make verify_entry_files +``` + ### [chk-entry.sh](chk-entry.sh) @@ -102,6 +108,7 @@ Usage: bin/gen-other-html.sh -v 1 ``` + ### [gen-sitemap.sh](gen-sitemap.sh) Generate an XML sitemap for the IOCCC web site. @@ -112,6 +119,12 @@ Usage: bin/gen-sitemap.sh -v 1 ``` +We recommend that this tool be invoked via the top level `Makefile`: + +```sh +make gen_sitemap +``` + ### [gen-status.sh](gen-status.sh) @@ -144,6 +157,12 @@ To see other valid statuses: bin/gen-status -h ``` +We recommend that this tool be invoked via the top level `Makefile`: + +```sh +make gen_status +``` + ### [gen-top-html.sh](gen-top-html.sh) @@ -170,6 +189,12 @@ Examples of top level HTML pages built by this tool include: - [news.html](../news.html) - [thanks-for-help.html](../thanks-for-help.html) +We recommend that this tool be invoked via the top level `Makefile`: + +```sh +make gen_top_html +``` + ### [gen-year-index.sh](gen-year-index.sh) @@ -181,6 +206,12 @@ Usage: bin/gen-year-index.sh -v 1 2020 ``` +We recommend that this tool be invoked via the top level `Makefile`: + +```sh +make gen_year_index +``` + ### [gen-years.sh](gen-years.sh) @@ -192,6 +223,12 @@ Usage: bin/gen-years.sh -v 1 ``` +We recommend that this tool be invoked via the top level `Makefile`: + +```sh +make gen_years +``` + ### [md2html.sh](md2html.sh) @@ -226,7 +263,7 @@ Wrapper tool to run pandoc. ### [quick-readme2index.sh](quick-readme2index.sh) -Runs [readme2index.sh](readme2index.sh) if the entry directory +Builds an entry's `index.html` file if the entry directory does not have a non-empty `index.hmtl` file, or if either `.entry.json` or `index.html` is newer than the `index.hmtl` file. @@ -250,8 +287,10 @@ bin/all-run.sh -v 3 bin/quick-readme2index.sh -v 1 modification times for `index.hmtl`, `.entry.json`, and `index.html` are correct. If in doubt, use: +We recommend that this tool be invoked via the top level `Makefile`: + ```sh -bin/all-run.sh -v 3 bin/readme2index.sh -v 1 +make quick_entry_index ``` @@ -259,6 +298,22 @@ bin/all-run.sh -v 3 bin/readme2index.sh -v 1 Convert an entry README.md into entry directory index.html. +```sh +bin/all-run.sh -v 3 bin/readme2index.sh -v 1 +``` + +To build `index.html` files for all entries: + +```sh +bin/all-run.sh -v 3 bin/readme2index.sh -v 1 +``` + +We recommend that this tool be invoked via the top level `Makefile`: + +```sh +make entry_index +``` + ### [status2html.sh](status2html.sh) @@ -296,6 +351,12 @@ Suggested usage: bin/all-run.sh bin/sort.gitignore.sh -v 1 ``` +We recommend that this tool be invoked via the top level `Makefile`: + +```sh +make sort_gitignore +``` + ### [subst.default.sh](subst.default.sh) @@ -349,6 +410,12 @@ Usage: bin/tar-all.sh -v 1 ``` +We recommend that this tool be invoked via the top level `Makefile`: + +```sh +make form_entry_tarball +``` + ## [tar-year.sh](tar-year.sh) @@ -366,6 +433,12 @@ Suggested usage: bin/all-years.sh -v 3 bin/tar-year.sh -v 1 -W ``` +We recommend that this tool be invoked via the top level `Makefile`: + +```sh +make form_year_tarball +``` + ## [untar-entry.sh](untar-entry.sh) @@ -383,6 +456,35 @@ Suggested usage: bin/all-run.sh -v 3 bin/untar-entry.sh -v 1 ``` +We recommend that this tool be invoked via the top level `Makefile`: + +```sh +make untar_entry_tarball +``` + + +## [untar-year.sh](untar-year.sh) + +Untar an IOCCC year's compressed tarball. + +Usage: + +```sh +bin/untar-year.sh -v 1 YYYY +``` + +Suggested usage: + +```sh +bin/all-years.sh -v 3 bin/untar-year.sh -v 1 +``` + +We recommend that this tool be invoked via the top level `Makefile`: + +```sh +make untar_year_tarball +``` + # How IOCCC HTML content is built diff --git a/bin/gen-year-index.sh b/bin/gen-year-index.sh index 83f35b807..bec150de1 100755 --- a/bin/gen-year-index.sh +++ b/bin/gen-year-index.sh @@ -85,7 +85,7 @@ shopt -s globstar # enable ** to match all files and zero or more directories an # set variables referenced in the usage message # -export VERSION="1.0.4 2024-03-26" +export VERSION="1.0.5 2024-03-28" NAME=$(basename "$0") export NAME export V_FLAG=0 @@ -312,8 +312,12 @@ if [[ $V_FLAG -ge 3 ]]; then echo "$0: debug[3]: now in directory: $(/bin/pwd)" 1>&2 fi -# verify that YYYY is a entry directory +# verify that YYYY is an IOCCC year directory # +if [[ ! -e $YYYY ]]; then + echo "$0: ERROR: arg does not exist: $YYYY" 1>&2 + exit 6 +fi if [[ ! -d $YYYY ]]; then echo "$0: ERROR: arg is not a directory: $YYYY" 1>&2 exit 6 @@ -325,21 +329,21 @@ fi # verify that YYYY has a non-empty readable .year file # -export YEAR_FILE="$YYYY/.year" -if [[ ! -e $YEAR_FILE ]]; then - echo "$0: ERROR: YYYY/.year does not exist: $YEAR_FILE" 1>&2 +export DOT_YEAR="$YYYY/.year" +if [[ ! -e $DOT_YEAR ]]; then + echo "$0: ERROR: YYYY/.year does not exist: $DOT_YEAR" 1>&2 exit 6 fi -if [[ ! -f $YEAR_FILE ]]; then - echo "$0: ERROR: YYYY/.year is not a regular file: $YEAR_FILE" 1>&2 +if [[ ! -f $DOT_YEAR ]]; then + echo "$0: ERROR: YYYY/.year is not a regular file: $DOT_YEAR" 1>&2 exit 6 fi -if [[ ! -r $YEAR_FILE ]]; then - echo "$0: ERROR: YYYY/.year is not an readable file: $YEAR_FILE" 1>&2 +if [[ ! -r $DOT_YEAR ]]; then + echo "$0: ERROR: YYYY/.year is not an readable file: $DOT_YEAR" 1>&2 exit 6 fi -if [[ ! -s $YEAR_FILE ]]; then - echo "$0: ERROR: YYYY/.year is not a non-empty readable file: $YEAR_FILE" 1>&2 +if [[ ! -s $DOT_YEAR ]]; then + echo "$0: ERROR: YYYY/.year is not a non-empty readable file: $DOT_YEAR" 1>&2 exit 6 fi @@ -404,7 +408,7 @@ if [[ $V_FLAG -ge 3 ]]; then echo "$0: debug[3]: YYYY=$YYYY" 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]: YEAR_FILE=$YEAR_FILE" 1>&2 + echo "$0: debug[3]: DOT_YEAR=$DOT_YEAR" 1>&2 echo "$0: debug[3]: README_FILE=$README_FILE" 1>&2 fi diff --git a/bin/index.html b/bin/index.html index 439def031..c467b8895 100644 --- a/bin/index.html +++ b/bin/index.html @@ -133,48 +133,54 @@ repo.
bin/all-years.sh -v 1 bin/gen-year-index.sh -v 1Or for example:
bin/all-years.sh -v 1 bin/chk-entry.shWe recommend that this tool be invoked via the top level Makefile:
make verify_entry_filesCheck that files required by an entry match the entry’s manifest as found in
.entry.json.
For example:
-bin/chk-entry.sh 2020/ferguson1bin/chk-entry.sh 2020/ferguson1Generate the list of files in the entry’s manifest, .entry.json.
For example:
-awk -f bin/filelist.entry.json.awk 2020/ferguson1/.entry.jsonawk -f bin/filelist.entry.json.awk 2020/ferguson1/.entry.jsonGenerate the top level /authors.html page.
Usage:
-bin/gen-authors.sh -v 1bin/gen-authors.sh -v 1Generate the top level /location.html page.
Usage:
-bin/gen-location.sh -v 1bin/gen-location.sh -v 1Generate entry HTML files (other than README.md to index.html) from markdown files.
Usage:
-bin/gen-other-html.sh -v 1bin/gen-other-html.sh -v 1Generate an XML sitemap for the IOCCC web site.
Usage:
-bin/gen-sitemap.sh -v 1bin/gen-sitemap.sh -v 1We recommend that this tool be invoked via the top level Makefile:
make gen_sitemapGenerate status.json according to the modification dates of status.json
and news.html.
Without argument, the contest_status is unchanged.
Usage:
-bin/gen-status.sh -v 1bin/gen-status.sh -v 1To force the contest_status to be closed:
bin/gen-status.sh -v 1 closedbin/gen-status.sh -v 1 closedTo force the contest_status to be open:
bin/gen-status.sh -v 1 openbin/gen-status.sh -v 1 openTo see other valid statuses:
-bin/gen-status -hbin/gen-status -hWe recommend that this tool be invoked via the top level Makefile:
make gen_statusGenerate a number of top level HTML pages for the IOCCC web sites.
Usage:
-bin/gen-top-html.sh -v 1bin/gen-top-html.sh -v 1Examples of top level HTML pages built by this tool include:
news.html.
We recommend that this tool be invoked via the top level Makefile:
make gen_top_htmlGenerate an index.html page for an given IOCCC year.
Usage:
-bin/gen-year-index.sh -v 1 2020bin/gen-year-index.sh -v 1 2020We recommend that this tool be invoked via the top level Makefile:
make gen_year_indexGenerate the top level /years.html page.
Usage:
-bin/gen-years.sh -v 1bin/gen-years.sh -v 1We recommend that this tool be invoked via the top level Makefile:
make gen_yearsThis is the primary tool that forms IOCCC generated HTML content from markdown files (permanent markdown files or temporarily generated @@ -214,7 +226,7 @@ page.
Wrapper tool to run pandoc.
Runs readme2index.sh if the entry directory +
Builds an entry’s index.html file if the entry directory
does not have a non-empty index.hmtl file, or if either
.entry.json or index.html is newer than the index.hmtl file.
This is useful when only a few entries have been @@ -226,13 +238,19 @@ the extra time can add up.
If only a few index.hmtl files need updating, then
this command will only briefly pause while the
slightly longer readme2index.sh is run:
bin/all-run.sh -v 3 bin/quick-readme2index.sh -v 1bin/all-run.sh -v 3 bin/quick-readme2index.sh -v 1NOTE: This command assumes that the relative
modification times for index.hmtl, .entry.json,
and index.html are correct. If in doubt, use:
bin/all-run.sh -v 3 bin/readme2index.sh -v 1We recommend that this tool be invoked via the top level Makefile:
make quick_entry_indexConvert an entry README.md into entry directory index.html.
+bin/all-run.sh -v 3 bin/readme2index.sh -v 1To build index.html files for all entries:
bin/all-run.sh -v 3 bin/readme2index.sh -v 1We recommend that this tool be invoked via the top level Makefile:
make entry_indexConvert status.json into HTML.
This tool is a ‘before tool’ (-b tool) that is intended
@@ -247,9 +265,11 @@ We sort with lines starting with ! fourth.
Sort a .gitignore in a entry directory.
Usage:
-bin/sort.gitignore.sh -v 1 YYYY/dirbin/sort.gitignore.sh -v 1 YYYY/dirSuggested usage:
-bin/all-run.sh bin/sort.gitignore.sh -v 1bin/all-run.sh bin/sort.gitignore.sh -v 1We recommend that this tool be invoked via the top level Makefile:
make sort_gitignorePrint default substitutions.
! fourth.
Form a compressed tarball for an entry.
Usage:
-bin/tar-entry.sh -v 1 YYYY/dirbin/tar-entry.sh -v 1 YYYY/dirSuggested usage:
-bin/all-run.sh -v 3 bin/tar-entry.sh -v 1 -Wbin/all-run.sh -v 3 bin/tar-entry.sh -v 1 -WForm the compressed tarball for all IOCCC years and all IOCCC entries.
Usage:
-bin/tar-all.sh -v 1bin/tar-all.sh -v 1We recommend that this tool be invoked via the top level Makefile:
make form_entry_tarballForm a compressed tarball for an IOCCC year.
Usage:
-bin/tar-year.sh -v 1 YYYYbin/tar-year.sh -v 1 YYYYSuggested usage:
-bin/all-years.sh -v 3 bin/tar-year.sh -v 1 -Wbin/all-years.sh -v 3 bin/tar-year.sh -v 1 -WWe recommend that this tool be invoked via the top level Makefile:
make form_year_tarballUntar an entry’s a compressed tarball.
Usage:
-bin/untar-entry.sh -v 1 YYYY/dirbin/untar-entry.sh -v 1 YYYY/dirSuggested usage:
-bin/all-run.sh -v 3 bin/untar-entry.sh -v 1bin/all-run.sh -v 3 bin/untar-entry.sh -v 1We recommend that this tool be invoked via the top level Makefile:
make untar_entry_tarballUntar an IOCCC year’s compressed tarball.
+Usage:
+bin/untar-year.sh -v 1 YYYYSuggested usage:
+bin/all-years.sh -v 3 bin/untar-year.sh -v 1We recommend that this tool be invoked via the top level Makefile:
make untar_year_tarballThe md2html.sh tool is the primary tool that is used to form all IOCCC related HTML pages for the official IOCCC web @@ -298,16 +332,16 @@ built uses, by default, files from the inc directory the file name form:
*.default.html
By using command line options of the form:
--H phase=name-H phase=namewhere phase is the name of an HTML phase,
a non-default file may be used. For example:
-H topnav=up2index-H topnav=up2indexwill cause inc/topnav.up2index.html instead of inc/topnav.default.html to be used during the topnav HTML phase.
If name is dot (i.e., .), then the given HTML phase is skipped.
For example:
-H footer=.-H footer=.will cause no HTML content to be produced during the footer HTML phase.
The following HTML phase files are used to build HTML content:
diff --git a/bin/sort.gitignore.sh b/bin/sort.gitignore.sh index c3b659872..abc8cb4c4 100755 --- a/bin/sort.gitignore.sh +++ b/bin/sort.gitignore.sh @@ -99,7 +99,7 @@ shopt -s globstar # enable ** to match all files and zero or more directories an # set variables referenced in the usage message # -export VERSION="1.1.3 2024-03-26" +export VERSION="1.1.4 2024-03-28" NAME=$(basename "$0") export NAME export V_FLAG=0 @@ -430,14 +430,20 @@ if [[ -z $NOOP ]]; then echo "$0: ERROR: sgi.sh failed, error: $status" 1>&2 exit 12 fi - if [[ $V_FLAG -ge 1 ]]; then - echo "$0: debug[1]: about to execute: mv -f $TMP_FILE $GITIGNORE" 1>&2 - fi - mv -f "$TMP_FILE" "$GITIGNORE" - status="$?" - if [[ $status -ne 0 ]]; then - echo "$0: ERROR: sgi.sh failed, error: $status" 1>&2 - exit 13 + if cmp -s "$TMP_FILE" "$GITIGNORE"; then + if [[ $V_FLAG -ge 1 ]]; then + echo "$0: debug[1]: $GITIGNORE is already sorted" 1>&2 + fi + else + if [[ $V_FLAG -ge 1 ]]; then + echo "$0: debug[1]: about to execute: mv -f $TMP_FILE $GITIGNORE" 1>&2 + fi + mv -f "$TMP_FILE" "$GITIGNORE" + status="$?" + if [[ $status -ne 0 ]]; then + echo "$0: ERROR: sgi.sh failed, error: $status" 1>&2 + exit 13 + fi fi elif [[ $V_FLAG -ge 1 ]]; then echo "$0: debug[1]: -n disabled execution of: $SGI_TOOL < $GITIGNORE > $TMP_FILE" 1>&2 diff --git a/bin/tar-year.sh b/bin/tar-year.sh index fcd5f9422..e4bfda0ca 100755 --- a/bin/tar-year.sh +++ b/bin/tar-year.sh @@ -83,7 +83,7 @@ shopt -s globstar # enable ** to match all files and zero or more directories an # set variables referenced in the usage message # -export VERSION="1.2 2024-03-27" +export VERSION="1.2.1 2024-03-28" NAME=$(basename "$0") export NAME export V_FLAG=0 @@ -645,26 +645,28 @@ if [[ -z $NOOP ]]; then # use the entry's manifest to add files to the IOCCC year's manifest, excluding the entry's tarball file # - awk -f "$FILELIST_ENTRY_JSON_AWK" "$ENTRY_JSON" >> "$TMP_MANIFEST_LIST" - status="$?" - if [[ $status -ne 0 ]]; then - echo "$0: ERROR: awk -f $FILELIST_ENTRY_JSON_AWK $ENTRY_JSON >> $TMP_MANIFEST_LIST failed, error: $status" 1>&2 - exit 1 - fi - - # remove entry's tarball from the IOCCC year's manifest + # We do not include the entry's tarball from the IOCCC year's manifest # export ENTRY_ID="${YEAR_DIR}_${ENTRY_DIR}" - sed -i '' -e "/$ENTRY_ID\.tar\.bz2$/d" "$TMP_MANIFEST_LIST" - status="$?" + if [[ $V_FLAG -ge 5 ]]; then + echo "$0: debug[5]: about to execute: awk -f $FILELIST_ENTRY_JSON_AWK $ENTRY_JSON |" \ + "grep -v \"/$ENTRY_ID\.tar\.bz2$\" >> $TMP_MANIFEST_LIST" 1>&2 + fi + awk -f "$FILELIST_ENTRY_JSON_AWK" "$ENTRY_JSON" | \ + grep -v "/$ENTRY_ID\.tar\.bz2$" >> "$TMP_MANIFEST_LIST" + status="${PIPESTATUS[0]}" if [[ $status -ne 0 ]]; then - echo "$0: ERROR: sed -i '' -e '/$ENTRY_ID.tar.bz2/d' $TMP_MANIFEST_LIST failed, error: $status" 1>&2 + echo "$0: ERROR: awk -f $FILELIST_ENTRY_JSON_AWK $ENTRY_JSON |" \ + "grep -v -F \"/$ENTRY_ID\.tar\.bz2$\" >> $TMP_MANIFEST_LIST failed, error: $status" 1>&2 exit 1 fi done # sort the manifest list # + if [[ $V_FLAG -ge 5 ]]; then + echo "$0: debug[5]: about to execute: LC_ALL=C sort -d $TMP_MANIFEST_LIST -o $TMP_MANIFEST_LIST" 1>&2 + fi LC_ALL=C sort -d "$TMP_MANIFEST_LIST" -o "$TMP_MANIFEST_LIST" status="$?" if [[ $status -ne 0 ]]; then diff --git a/bin/untar-year.sh b/bin/untar-year.sh new file mode 100755 index 000000000..4d828a39a --- /dev/null +++ b/bin/untar-year.sh @@ -0,0 +1,387 @@ +#!/usr/bin/env bash +# +# untar-year.sh - untar files belonging to an IOCCC year +# +# Copyright (c) 2024 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 + +# set variables referenced in the usage message +# +export VERSION="1.0 2024-03-28" +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 +export REPO_URL="https://github.com/ioccc-src/temp-test-ioccc" +export CAP_W_FLAG_FOUND= +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 8 +fi + +# set usage message +# +export USAGE="usage: $0 [-h] [-v level] [-V] [-d topdir] [-D docroot/] [-n] [-N] + [-p tool] [-u repo_url] [-w site_url] [-W] + YYYY + + -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) + -D docroot/ This option is ignored + + -n go thru the actions, but do not update any files (def: do the action) + -N do not process file, just parse arguments and ignore the file (def: process the file) + + -p tool This option is ignored + + -u repo_url This option is ignored + -w site_url This option is ignored + + -W Warn if a file in the manifest is missing: (def: error if a file is missing) + + YYYY IOCCC year + +Exit codes: + 0 all OK + 1 some internal tool exited non-zero + 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 problems found with or in the entry topdir/YYYY/dir directory + 8 gnu tar is missing or execution failed or error in forming compressed tarball + >= 10 internal error + +$NAME version: $VERSION" + +# setup +# +export NOOP= +export DO_NOT_PROCESS= + +# parse command line +# +while getopts :hv:Vd:D:nNp:u:U:w:W flag; do + case "$flag" in + h) echo "$USAGE" 1>&2 + exit 2 + ;; + v) V_FLAG="$OPTARG" + ;; + V) echo "$VERSION" + exit 2 + ;; + d) TOPDIR="$OPTARG" + ;; + D) ;; + n) NOOP="-n" + ;; + N) DO_NOT_PROCESS="-N" + ;; + p) ;; + u) ;; + U) ;; + w) ;; + W) CAP_W_FLAG_FOUND="true" + ;; + \?) echo "$0: ERROR: invalid option: -$OPTARG" 1>&2 + echo 1>&2 + print_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 + +# parse the command line arguments +# +if [[ $V_FLAG -ge 3 ]]; then + echo "$0: debug[3]: debug level: $V_FLAG" 1>&2 +fi +# +shift $(( OPTIND - 1 )); +# +if [[ $V_FLAG -ge 5 ]]; then + echo "$0: debug[5]: file argument count: $#" 1>&2 +fi +if [[ $# -ne 1 ]]; then + echo "$0: ERROR: expected 1 arg, found: $#" 1>&2 + exit 3 +fi +# +export YYYY="$1" + +# verify that we have a topdir directory +# +REPO_NAME=$(basename "$REPO_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_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_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_URL; cd $REPO_NAME" 1>&2 + exit 6 +fi + +# 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 that YYYY is an IOCCC year directory +# +if [[ ! -e $YYYY ]]; then + echo "$0: ERROR: arg does not exist: $YYYY" 1>&2 + exit 6 +fi +if [[ ! -d $YYYY ]]; then + echo "$0: ERROR: arg is not a directory: $YYYY" 1>&2 + exit 6 +fi +if [[ ! -r $YYYY ]]; then + echo "$0: ERROR: arg is not a writable directory: $YYYY" 1>&2 + exit 6 +fi + +# verify that YYYY has a non-empty readable .year file +# +export DOT_YEAR="$YYYY/.year" +if [[ ! -e $DOT_YEAR ]]; then + echo "$0: ERROR: YYYY/.year does not exist: $DOT_YEAR" 1>&2 + exit 6 +fi +if [[ ! -f $DOT_YEAR ]]; then + echo "$0: ERROR: YYYY/.year is not a regular file: $DOT_YEAR" 1>&2 + exit 6 +fi +if [[ ! -r $DOT_YEAR ]]; then + echo "$0: ERROR: YYYY/.year is not an readable file: $DOT_YEAR" 1>&2 + exit 6 +fi +if [[ ! -s $DOT_YEAR ]]; then + echo "$0: ERROR: YYYY/.year is not a non-empty readable file: $DOT_YEAR" 1>&2 + exit 6 +fi + +# determine the name of our tarball +# +# TARBALL - the same of the compressed tarball to verify and if needed re-build +# REBUILD_TARBALL - if non-empty, we need to re-build TARBALL and update tar timestamps +# +export TARBALL="$YYYY/$YYYY.tar.bz2" + +# test - if needed - if the tarball is a non-empty writable file +# +if [[ ! -e $TARBALL ]]; then + echo "$0: ERROR: tarball does not exist: $TARBALL" 1>&2 + exit 1 +fi +if [[ ! -f $TARBALL ]]; then + echo "$0: ERROR: tarball is not a file: $TARBALL" 1>&2 + exit 1 +fi +if [[ ! -w $TARBALL ]]; then + echo "$0: ERROR: tarball is not a writable file: $TARBALL" 1>&2 + exit 1 +fi +if [[ ! -s $TARBALL ]]; then + echo "$0: ERROR: tarball is not a non-empty writable file: $TARBALL" 1>&2 + exit 1 +fi + +# parameter debugging +# +if [[ $V_FLAG -ge 3 ]]; then + 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]: REPO_URL=$REPO_URL" 1>&2 + echo "$0: debug[3]: CAP_W_FLAG_FOUND=$CAP_W_FLAG_FOUND" 1>&2 + echo "$0: debug[3]: GTAR_TOOL=$GTAR_TOOL" 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]: YYYY=$YYYY" 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]: DOT_YEAR=$DOT_YEAR" 1>&2 + echo "$0: debug[3]: TARBALL=$TARBALL" 1>&2 +fi + +# If -N, time to exit +# +if [[ -n $DO_NOT_PROCESS ]]; then + if [[ $V_FLAG -ge 1 ]]; then + echo "$0: debug[1]: arguments parsed, -N given, exit 0" 1>&2 + fi + exit 0 +fi + +# untar entry compressed tarball +# +if [[ -z $NOOP ]]; then + + # case: form the tarball verbosely if -v 5 or more + # + if [[ $V_FLAG -ge 1 ]]; then + echo "$0: debug[1]: about to execute:" \ + "$GTAR_TOOL --totals -jxvf $TARBALL" 1>&2 + "$GTAR_TOOL" --totals -jxvf "$TARBALL" + status="$?" + if [[ $status -ne 0 ]]; then + echo "$0: ERROR:" \ + "$GTAR_TOOL --totals -jxvf $TARBALL failed, error: $status" 1>&2 + exit 8 + fi + + # case: form the tarball silently + # + else + "$GTAR_TOOL" -jxf "$TARBALL" + status="$?" + if [[ $status -ne 0 ]]; then + echo "$0: ERROR:" \ + "$GTAR_TOOL -jxf $TARBALL failed, error: $status" 1>&2 + exit 8 + fi + fi + +# case: -n +# +elif [[ $V_FLAG -ge 5 ]]; then + echo "$0: debug[5]: because of -n, did not execute:" \ + "$GTAR_TOOL --totals -jxvf $TARBALL" 1>&2 +fi + +# All Done!!! -- Jessica Noll, Age 2 +# +exit 0