#! /bin/sh

# Create git repositories from project directories/tarballs.
#
# Usage example:
#
# ./init [--unpack]
#
owd=`pwd`
trap "{ cd $owd; exit 1; }" ERR
set -o errtrace # Trap in functions.

function info  () { echo "$*" 1>&2; }
function error () { info "error: $*"; exit 1; }
function trace () { if [ "$verbose" == 'y' ]; then info "trace: $*"; fi }

unpack=

while [ $# -gt 0 ]; do
  case $1 in
    --unpack)
      unpack='y'
      shift
      ;;
    *)
      error "invalid option $1"
      ;;
  esac
done

# Unpack repositories if requested.
#
if [ -n "$unpack" ]; then
  for f in */*.tar; do
    rm -r -f ${f%.tar}.git
    tar xf $f;
  done
fi

# Create the initial state of the repositories libfoo.git, libfox.git,
# libbar.git, style.git, and style-basic.git.
#
cd state0

rm -f -r links.git/.git
rm -f    links.git/.gitmodules
rm -f    links.git/bl
rm -f    links.git/lc
rm -f    links.git/pg
rm -f    links.git/bs
rm -f    links.git/bf
rm -f    links.git/tl
rm -f    links.git/td
rm -f    links.git/ts
rm -f -r links.git/doc/style

rm -f -r libfoo.git/.git
rm -f    libfoo.git/.gitmodules
rm -f    libfoo.git/README
rm -f -r libfoo.git/libbar
rm -f -r libfoo.git/doc/style

rm -f -r libfox.git/.git
rm -f    libfox.git/.gitmodules
rm -f -r libfox.git/libbar

rm -f -r libbar.git/.git
rm -f    libbar.git/.gitmodules
rm -f -r libbar.git/extras

rm -f -r style.git/.git
rm -f -r style.git/basic

rm -f -r style-basic.git/.git
rm -f    style-basic.git/README
rm -f    style-basic.git/INSTALL
rm -f    style-basic.git/repositories.manifest

# Create master branch for style-basic.git.
#
git -C style-basic.git init
git -C style-basic.git add '*'
git -C style-basic.git commit -am 'Create' --no-verify

# Create stable branch for style-basic.
#
sleep 1 # Make sure that master commits are older than stable commits.
git -C style-basic.git branch stable
git -C style-basic.git checkout stable
echo "TODO" >style-basic.git/README
cat <<EOF >style-basic.git/repositories.manifest
: 1
email: user@example.com
EOF
git -C style-basic.git add README repositories.manifest
git -C style-basic.git commit -am 'README' --no-verify

# Create master branch for style.git, adding style-basic.git as a submodule.
#
git -C style.git init
git -C style.git add '*'
git -C style.git submodule add ../style-basic.git basic # The stable branch.
git -C style.git commit -am 'Create' --no-verify

# Make style.git to refer an unadvertised reference, commiting into the stable
# branch of style-basic.git.
#
touch style-basic.git/INSTALL
git -C style-basic.git add INSTALL
git -C style-basic.git commit -am 'INSTALL' --no-verify
git -C style-basic.git checkout master

# Create master branch for libbar.git.
#
git -C libbar.git init

cat <<EOF >libbar.git/libbar/manifest
: 1
name: libbar
version: 1.0.0
summary: libbar
license: MIT
description-file: README
url: http://example.org/libbar
email: pkg@example.org
depends: style-basic >= $
EOF

git -C libbar.git add '*'
git -C libbar.git commit -am 'Create' --no-verify
git -C libbar.git tag -a 'v1.0.0' -m 'Tag version 1.0.0'

git -C libbar.git submodule add -b stable ../style-basic.git extras
cat <<EOF >libbar.git/libbar/manifest
: 1
name: libbar
version: 1.0.0+1
summary: libbar
license: MIT
description-file: README
url: http://example.org/libbar
email: pkg@example.org
depends: style-basic >= $
EOF

git -C libbar.git commit -am 'Add extras' --no-verify
git -C libbar.git tag -a 'v1.0.0+1' -m 'Tag version 1.0.0+1'

# Create master branch for libfoo.git, adding style.git and libbar.git as
# submodules.
#
git -C libfoo.git init

cat <<EOF >libfoo.git/manifest
: 1
name: libfoo
version: 0.0.1
summary: libfoo
license: MIT
url: http://example.org
email: pkg@example.org
EOF

git -C libfoo.git add '*'
git -C libfoo.git submodule add ../style.git doc/style
git -C libfoo.git submodule add ../libbar.git libbar
git -C libfoo.git submodule update --init --recursive # Updates doc/style/basic.
git -C libfoo.git commit -am 'Create' --no-verify
git -C libfoo.git tag -a 'v0.0.1' -m 'Tag version 0.0.1'

# Increase libfoo version and add tags.
#
cat <<EOF >libfoo.git/manifest
: 1
name: libfoo
version: 1.0.0
summary: libfoo
license: MIT
url: http://example.org
email: pkg@example.org
EOF

git -C libfoo.git commit -am 'Increase version to 1.0.0' --no-verify

git -C libfoo.git tag 'ltag'
git -C libfoo.git tag -a 'atag'   -m 'Create annotated tag'
git -C libfoo.git tag -a 'v1.0.0' -m 'Tag version 1.0.0'

# Advance the master branch to make tags not to mark a branch tip.
#
touch  libfoo.git/README
git -C libfoo.git add README
git -C libfoo.git commit -am 'README' --no-verify

# Create master branch for libfox.git, adding libbar.git as a submodule.
#
git -C libfox.git init
git -C libfox.git add '*'
git -C libfox.git submodule add ../libbar.git libbar
git -C libfox.git submodule update --init --recursive # Recursive for safety.
git -C libfox.git commit -am 'Create' --no-verify

# Create master branch for links.git, adding style.git as a submodule.
#
git -C links.git init

cat <<EOF >links.git/manifest
: 1
name: links
version: 0.0.1
summary: links
license: MIT
url: http://example.org
email: pkg@example.org
EOF

git -C links.git add '*'
git -C links.git submodule add ../style.git doc/style
git -C links.git submodule update --init --recursive # Updates doc/style/basic.
git -C links.git commit -am 'Create' --no-verify
git -C links.git tag -a 'v0.0.1' -m 'Tag version 0.0.1'

# Increase links version and add symlinks.
#
cat <<EOF >links.git/manifest
: 1
name: links
version: 1.0.0-a.0.z
summary: links
license: MIT
url: http://example.org
email: pkg@example.org
EOF

ln -s tests links.git/ts               # Directory symlink.
ln -s ts/TODO links.git/td             # File symlink via directory symlink.
ln -s td links.git/tl                  # Symlink symlink.
ln -s doc/style/buildfile links.git/bf # Submodule file symlink.
ln -s doc/style/basic links.git/bs     # Submodule directory symlink.
ln -s bs/page.css links.git/pg         # Symlink via submodule directory symlink.

git -C links.git add '*'
git -C links.git commit -am 'Add symlinks' --no-verify
git -C links.git tag -a 'v1.0.0-alpha' -m 'Tag version 1.0.0-alpha'

# Increase links version and add dangling symlink.
#
cat <<EOF >links.git/manifest
: 1
name: links
version: 1.0.1
summary: links
license: MIT
url: http://example.org
email: pkg@example.org
EOF

ln -s lc links.git/bl # Dangling symlink.

git -C links.git add '*'
git -C links.git commit -am 'Add dangling symlinks' --no-verify
git -C links.git tag -a 'v1.0.1' -m 'Tag version 1.0.1'

# Increase links version and add cyclic symlink.
#
cat <<EOF >links.git/manifest
: 1
name: links
version: 1.0.2
summary: links
license: MIT
url: http://example.org
email: pkg@example.org
EOF

ln -s bl links.git/lc # Cyclic symlink.

git -C links.git add '*'
git -C links.git commit -am 'Add cyclic symlinks' --no-verify
git -C links.git tag -a 'v1.0.2' -m 'Tag version 1.0.2'


# Create the modified state of the repositories, replacing libbar.git submodule
# of libfoo with the newly created libbaz.git repository. Also advance master
# branches and tags for libfoo.git and it's submodule style.git.
#
cd ../state1

# Copy repositories initial state.
#
for d in ../state0/*.git; do
  rm -f -r $(basename $d)
  cp -r $d .
done

# Drop the links.git repository.
#
rm -f -r links.git/

# Create libbaz.git repository.
#
rm -f -r libbaz.git/.git

git -C libbaz.git init
git -C libbaz.git add '*'
git -C libbaz.git commit -am 'Create' --no-verify

# Sync submodule references with their new locations.
#
for d in *.git; do
  git -C $d  submodule sync --recursive
done

# Advance style.git master branch.
#
touch  style.git/README
git -C style.git add README
git -C style.git commit -am 'README' --no-verify

# Advance libfoo.git master branch.
#
git -C libfoo.git submodule update --init --remote # Pull style only.
git -C libfoo.git commit -am 'Update style' --no-verify

git -C libfoo.git rm -r tests
git -C libfoo.git commit -am 'Remove tests' --no-verify

git -C libfoo.git submodule deinit libbar
git -C libfoo.git rm libbar
git -C libfoo.git commit -am 'Remove libbar' --no-verify
rm -f -r libbar.git

git -C libfoo.git submodule add ../libbaz.git libbaz
git -C libfoo.git submodule update --init libbaz
git -C libfoo.git commit -am 'Add libbaz' --no-verify

git -C libfoo.git tag -f 'ltag'
git -C libfoo.git tag -f -a 'atag' -m 'Move annotated tag'

touch  libfoo.git/INSTALL
git -C libfoo.git add INSTALL
git -C libfoo.git commit -am 'INSTALL' --no-verify