run_development_cycle.sh
#!/bin/bash

# Copyright 2017-2018 Vincent Jacques <vincent@vincent-jacques.net>

# GENI: prologue
# GENERATED SECTION, MANUAL EDITS WILL BE LOST
set -o errexit -o pipefail
IFS=$'\n\t'

PROJECT_ROOT=$(pwd)

SHOW_IN_BROWSER=false
function show_in_browser {
  echo
  echo "$1: $PROJECT_ROOT/$2"
  echo
  if $SHOW_IN_BROWSER
  then
    python -m webbrowser -t file://$PROJECT_ROOT/$2
  fi
}

DO_OPAM_INSTALL=true
DO_OPAM_REMOVE=true
DO_OPAM_UPGRADE=true

while [[ "$#" > 0 ]]
do
  case $1 in
    -wb|--web-browser)
      SHOW_IN_BROWSER=true
      ;;
    --skip-opam-install)
      DO_OPAM_INSTALL=false
      ;;
    --skip-opam-remove)
      DO_OPAM_REMOVE=false
      ;;
    --skip-opam-upgrade)
      DO_OPAM_UPGRADE=false
      ;;
    -q|--quick)
      DO_OPAM_INSTALL=false
      DO_OPAM_REMOVE=false
      DO_OPAM_UPGRADE=false
      ;;
    *)
      echo "Unknown parameter passed: $1"
      exit 1;;
  esac
  shift
done

function opam_switch {
  eval `opam config env --switch=$1 --set-switch`
}

function dune_ {
  SWITCH=$1
  shift
  FLAVOR=$1
  shift

  opam_switch $SWITCH
  rm -rf _build
  DIRECTORY=_builds/$SWITCH/$FLAVOR
  mkdir -p $DIRECTORY
  ln -sf $DIRECTORY _build
  for gen in $(find . -name dune.py)
  do
    $gen $FLAVOR >${gen%.py}
  done

  find $DIRECTORY -name "*.sentinel" -delete
  dune "$@"

  rm -rf _build
  for gen in $(find . -name dune.py)
  do
    echo "; THIS FILE IS GENERATED by ./dune.py" >${gen%.py}
    echo "; MANUAL CHANGES WILL BE LOST" >>${gen%.py}
    echo "" >>${gen%.py}
    $gen publish >>${gen%.py}
  done
}
# END OF GENERATED SECTION


# GENI: install_dependencies
# GENERATED SECTION, MANUAL EDITS WILL BE LOST
DEV_WITH_OLDEST_VERSIONS=4.02.3.DrawGrammar.dev_with_oldest_versions
if ! opam switch list --short | grep "^$DEV_WITH_OLDEST_VERSIONS$" >/dev/null
then
  opam switch create $DEV_WITH_OLDEST_VERSIONS 4.02.3 --no-switch
fi
opam_switch $DEV_WITH_OLDEST_VERSIONS
opam install --yes General.0.6.0 JsOfOCairo.2.0.0 bisect-summary bisect_ppx cairo2.0.6 dune.1.4.0 menhir.20171222

DEV_WITH_NEWEST_VERSIONS=4.07.1.DrawGrammar.dev_with_newest_versions
if ! opam switch list --short | grep "^$DEV_WITH_NEWEST_VERSIONS$" >/dev/null
then
  opam switch create $DEV_WITH_NEWEST_VERSIONS 4.07.1 --no-switch
fi
opam_switch $DEV_WITH_NEWEST_VERSIONS
opam install --yes General JsOfOCairo cairo2 dune menhir
if $DO_OPAM_UPGRADE; then opam upgrade --yes; fi
# END OF GENERATED SECTION


opam_switch $DEV_WITH_NEWEST_VERSIONS
for p in src/*_Parser.mly
do
  m=${p%_Parser.mly}_Messages.messages
  c=${p%_Parser.mly}_Messages.ml
  menhir --list-errors $p > $m.dummies
  if [ -f $m ]
  then
    menhir --compare-errors $m.dummies --compare-errors $m $p
    rm $m.dummies
  else
    mv $m.dummies $m
  fi
  menhir --compile-errors $m $p > $c
done


# GENI: run_tests
# GENERATED SECTION, MANUAL EDITS WILL BE LOST
find _builds -name "*.sentinel" -delete
opam_switch $DEV_WITH_OLDEST_VERSIONS
dune_ $DEV_WITH_OLDEST_VERSIONS coverage runtest
echo
bisect-summary _builds/$DEV_WITH_OLDEST_VERSIONS/coverage/default/*/bisect????.out
bisect-ppx-report -I _builds/$DEV_WITH_OLDEST_VERSIONS/coverage/default -html _builds/$DEV_WITH_OLDEST_VERSIONS/coverage/default/bisect _builds/$DEV_WITH_OLDEST_VERSIONS/coverage/default/*/bisect????.out
show_in_browser "See coverage report" _builds/$DEV_WITH_OLDEST_VERSIONS/coverage/default/bisect/index.html

opam_switch $DEV_WITH_NEWEST_VERSIONS
dune_ $DEV_WITH_NEWEST_VERSIONS debug runtest
# END OF GENERATED SECTION


echo
dune_ $DEV_WITH_NEWEST_VERSIONS debug build src/draw_grammar.bc src/draw_grammar_js.bc.js

echo
_builds/$DEV_WITH_NEWEST_VERSIONS/debug/default/src/draw_grammar.bc --help

echo
cd docs
[ -e python2.7.python-ebnf ] || wget https://raw.githubusercontent.com/python/cpython/2.7/Grammar/Grammar --output-document python2.7.python-ebnf
[ -e python3.6.python-ebnf ] || wget https://raw.githubusercontent.com/python/cpython/3.6/Grammar/Grammar --output-document python3.6.python-ebnf
[ -e lex.ocaml-etex-ebnf ] || wget https://raw.githubusercontent.com/ocaml/ocaml/trunk/manual/manual/refman/lex.etex --output-document lex.ocaml-etex-ebnf
[ -e names.ocaml-etex-ebnf ] || wget https://raw.githubusercontent.com/ocaml/ocaml/trunk/manual/manual/refman/names.etex --output-document names.ocaml-etex-ebnf
[ -e types.ocaml-etex-ebnf ] || wget https://raw.githubusercontent.com/ocaml/ocaml/trunk/manual/manual/refman/types.etex --output-document types.ocaml-etex-ebnf
[ -e const.ocaml-etex-ebnf ] || wget https://raw.githubusercontent.com/ocaml/ocaml/trunk/manual/manual/refman/const.etex --output-document const.ocaml-etex-ebnf
[ -e patterns.ocaml-etex-ebnf ] || wget https://raw.githubusercontent.com/ocaml/ocaml/trunk/manual/manual/refman/patterns.etex --output-document patterns.ocaml-etex-ebnf
[ -e expr.ocaml-etex-ebnf ] || wget https://raw.githubusercontent.com/ocaml/ocaml/trunk/manual/manual/refman/expr.etex --output-document expr.ocaml-etex-ebnf
[ -e typedecl.ocaml-etex-ebnf ] || wget https://raw.githubusercontent.com/ocaml/ocaml/trunk/manual/manual/refman/typedecl.etex --output-document typedecl.ocaml-etex-ebnf
[ -e classes.ocaml-etex-ebnf ] || wget https://raw.githubusercontent.com/ocaml/ocaml/trunk/manual/manual/refman/classes.etex --output-document classes.ocaml-etex-ebnf
[ -e modtypes.ocaml-etex-ebnf ] || wget https://raw.githubusercontent.com/ocaml/ocaml/trunk/manual/manual/refman/modtypes.etex --output-document modtypes.ocaml-etex-ebnf
[ -e modules.ocaml-etex-ebnf ] || wget https://raw.githubusercontent.com/ocaml/ocaml/trunk/manual/manual/refman/modules.etex --output-document modules.ocaml-etex-ebnf
[ -e compunit.ocaml-etex-ebnf ] || wget https://raw.githubusercontent.com/ocaml/ocaml/trunk/manual/manual/refman/compunit.etex --output-document compunit.ocaml-etex-ebnf
# [ -e exten.ocaml-etex-ebnf ] || wget https://raw.githubusercontent.com/ocaml/ocaml/trunk/manual/manual/refman/exten.etex --output-document exten.ocaml-etex-ebnf
../_builds/$DEV_WITH_NEWEST_VERSIONS/debug/default/src/draw_grammar.bc arithmetics.iso-ebnf --inline digit --inline factor --inline not_a_rule
mv arithmetics.iso-ebnf.png arithmetics-inlined-digit-factor.iso-ebnf.png
../_builds/$DEV_WITH_NEWEST_VERSIONS/debug/default/src/draw_grammar.bc arithmetics.iso-ebnf --inline digit,factor,term --inline-keep integer
mv arithmetics.iso-ebnf.png arithmetics-inlined-all.iso-ebnf.png
../_builds/$DEV_WITH_NEWEST_VERSIONS/debug/default/src/draw_grammar.bc *.*-ebnf
mv *.*-ebnf.png ..
cd ..
echo
echo "Have a look at $PROJECT_ROOT/*.png"
echo


show_in_browser "Have a look at" drawing_tests.html

dune_ $DEV_WITH_NEWEST_VERSIONS release build --profile release src/draw_grammar_js.bc.js
cp _builds/$DEV_WITH_NEWEST_VERSIONS/release/default/src/draw_grammar_js.bc.js docs
show_in_browser "Have a look at" docs/index.html


# GENI: check_code
# GENERATED SECTION, MANUAL EDITS WILL BE LOST
# END OF GENERATED SECTION


# GENI: documentation
# GENERATED SECTION, MANUAL EDITS WILL BE LOST
# END OF GENERATED SECTION


# GENI: install
# GENERATED SECTION, MANUAL EDITS WILL BE LOST
if $DO_OPAM_INSTALL
then
  if ! opam switch list --short | grep "^4.07.1.DrawGrammar.pin_on_newest_ocaml$" >/dev/null
  then
    opam switch create 4.07.1.DrawGrammar.pin_on_newest_ocaml 4.07.1 --no-switch
  fi
  opam_switch 4.07.1.DrawGrammar.pin_on_newest_ocaml
  if $DO_OPAM_REMOVE
  then
    opam remove --yes --auto-remove $(opam list --short --installed-roots | grep -v -e "^ocaml-base-compiler$")
    opam pin list --short | grep "." && opam pin remove $(opam pin list --short)
  fi
  opam pin --yes --no-action add --kind=path .
  opam remove --yes DrawGrammar
  opam install --yes DrawGrammar --deps-only
  opam install --yes DrawGrammar --build-test

  if ! opam switch list --short | grep "^4.02.3.DrawGrammar.pin_on_oldest_ocaml$" >/dev/null
  then
    opam switch create 4.02.3.DrawGrammar.pin_on_oldest_ocaml 4.02.3 --no-switch
  fi
  opam_switch 4.02.3.DrawGrammar.pin_on_oldest_ocaml
  if $DO_OPAM_REMOVE
  then
    opam remove --yes --auto-remove $(opam list --short --installed-roots | grep -v -e "^ocaml-base-compiler$")
    opam pin list --short | grep "." && opam pin remove $(opam pin list --short)
  fi
  opam pin --yes --no-action add --kind=path .
  opam remove --yes DrawGrammar
  opam install --yes DrawGrammar --deps-only
  opam install --yes DrawGrammar --build-test
fi
# END OF GENERATED SECTION


# GENI: epilogue
# GENERATED SECTION, MANUAL EDITS WILL BE LOST
echo
echo "Development cycle OK"
# END OF GENERATED SECTION
