# file      : tests/pkg-checkout.testscript
# license   : MIT; see accompanying LICENSE file

.include common.testscript config.testscript remote-git.testscript

# Source repository:
#
# pkg-checkout
# `-- git
#     |-- libbar.git      -> style-basic.git (prerequisite)
#     `-- style-basic.git

posix = ($cxx.target.class != 'windows')

# Prepare repositories used by tests if running in the local mode.
#
+if! $remote
{
  # Create git repositories.
  #
  $git_extract $src/git/libbar.tar
  $git_extract $src/git/style-basic0.tar &$out_git/state0/***

  if $posix
  {
    $git_extract $src/git/style.tar
    $git_extract $src/git/links.tar
  }
}

: git-rep
:
if! $git_supported
{{
  # Skip git repository tests.
  #
}}
else
{{
  rep = "$rep_git/state0"

  rep_add       += -d cfg 2>!
  rep_fetch     += -d cfg 2>!
  pkg_configure += -d cfg 2>!
  pkg_disfigure += -d cfg 2>!
  pkg_purge     += -d cfg 2>!
  pkg_status    += -d cfg
  pkg_drop      += -d cfg --yes 2>!

  test.cleanups += &?cfg/.bpkg/repos/*/***

  : unconfigured-dependency
  :
  {
    $clone_root_cfg
    $rep_add "$rep/libbar.git#master"
    $rep_fetch

    $* libmbar/1.0.0 2>>~%EOE%
      checking out libmbar/1.0.0 (local cache)
      %.+
      distributing libmbar/1.0.0
      checked out libmbar/1.0.0
      EOE

    $pkg_purge libmbar
  }

  : configured-dependency
  :
  {
    $clone_root_cfg
    $rep_add "$rep/libbar.git#master" && $rep_add "$rep/style-basic.git#master"
    $rep_fetch

    $pkg_status style-basic | sed -n -e 's/style-basic available \[.+\] ([^ ]+)/\1/p' | set v

    $* "style-basic/$v" 2>>~"%EOE%"
      checking out style-basic/$v \(local cache\)
      verifying symlinks
      %fixing up symlinks%?
      distributing style-basic/$v
      checked out style-basic/$v
      EOE

    $pkg_configure style-basic

    $* libmbar/1.0.0 2>>~%EOE%
      checking out libmbar/1.0.0 (local cache)
      %.+
      distributing libmbar/1.0.0
      checked out libmbar/1.0.0
      EOE

    $pkg_disfigure style-basic

    $pkg_purge libmbar
    $pkg_purge style-basic
  }

  : replacement
  :
  {
    $clone_root_cfg
    $rep_add "$rep/style-basic.git#master,stable"
    $rep_fetch

    $pkg_status style-basic | \
      sed -n -e 's/style-basic available ([^ ]+) +([^ ]+)/\1 \2/p' | set vs

    echo "$vs" | sed -e 's/([^ ]+).+/\1/'        | set v0
    echo "$vs" | sed -e 's/([^ ]+) +([^ ]+)/\2/' | set v1

    $* "style-basic/$v0" 2>!
    $pkg_status style-basic >~"/style-basic unpacked $v0/"

    $* --replace "style-basic/$v1" 2>!
    $pkg_status style-basic >~"/style-basic unpacked $v1 .+/"

    $pkg_purge style-basic
  }

  : links
  :
  if ($remote || $posix)
  {
    $clone_root_cfg

    $rep_fetch "$rep/links.git#v1.0.0-alpha"

    $pkg_status links | sed -n -e 's/links available (.+)/\1/p' | set v

    $* "links/$v" 2>>~%EOE%
      %.*
      %checking out links/1.0.0-a.0.[^.]+.[^.]+%d
      %.*
      %distributing links/1.0.0-a.0.[^.]+.[^.]+%d
      %checked out links/1.0.0-a.0.[^.]+.[^.]+%d
      EOE

    d = "cfg/links-$v"

    # See common/git/init script for the symlinks descriptions.
    #
    test -d $d/bs
    test -d $d/ts

    cat $d/pg          >'h1 {font-size: 3em;}'
    cat $d/bs/page.css >'h1 {font-size: 3em;}'
    cat $d/bf          >'./: file{manifest}'
    cat $d/td          >'@@'
    cat $d/tl          >'@@'
    cat $d/ts/TODO     >'@@'

    $pkg_purge links
    $rep_fetch "$rep/links.git#v0.0.1"

    $* links/0.0.1 2>>~%EOE%
      checking out links/0.0.1 (local cache)
      %.*
      verifying symlinks
      %fixing up symlinks%?
      distributing links/0.0.1
      checked out links/0.0.1
      EOE

    d = cfg/links-0.0.1

    test -d $d/bs == 1
    test -d $d/ts == 1
    test -f $d/pg == 1
    test -f $d/bf == 1
    test -f $d/td == 1
    test -f $d/tl == 1

    $pkg_purge links

    # Dangling symlink in the repository.
    #
    $rep_fetch "$rep/links.git#v1.0.1"

    # Note that on POSIX the repository is restored in its permanent location,
    # since the operation fails in the distribution phase. This is in contrast
    # to Windows where the repository is lost, since the operation fails in
    # the fix-up phase.
    #
    if $posix
      $* links/1.0.1 2>>~%EOE% != 0
        checking out links/1.0.1 (local cache)
        %.*
        verifying symlinks
        %fixing up symlinks%?
        distributing links/1.0.1
        %warning: skipping dangling symlink .+%
        %error: unable to stat .+%
        EOE
    else
      $* links/1.0.1 2>>~%EOE% != 0
        checking out links/1.0.1 (local cache)
        %.*
        verifying symlinks
        %fixing up symlinks%?
        %error: target '.+' for symlink '.+' does not exist%
          info: re-run with -v for more information
        warning: repository state is now broken
          info: run 'bpkg rep-fetch' to repair
        EOE

    # Cyclic symlinks in the repository.
    #
    $rep_fetch "$rep/links.git#v1.0.2"

    if $posix
      $* links/1.0.2 2>>~%EOE% != 0
        %.*
        %error: unable to iterate over .+%
        EOE
    else
      $* links/1.0.2 2>>~%EOE% != 0
        checking out links/1.0.2 (local cache)
        %.*
        %error: target '..' for symlink '..' does not exist%
          info: re-run with -v for more information
        warning: repository state is now broken
          info: run 'bpkg rep-fetch' to repair
        EOE
  }

  : output-root
  :
  {{
    : no-purge
    :
    {
      $clone_root_cfg
      $rep_add "$rep/libbar.git#master"
      $rep_fetch

      $* --output-root $~ libmbar/1.0.0 &libmbar-1.0.0/*** 2>>~%EOE%
        checking out libmbar/1.0.0 (local cache)
        %.+
        distributing libmbar/1.0.0
        checked out libmbar/1.0.0
        EOE

      test -f libmbar-1.0.0/manifest

      # While at it, test that the package is buildable.
      #
      $pkg_build libmbar -d cfg/ --yes 2>!
      $pkg_drop libmbar
    }

    : purge
    :
    {
      $clone_root_cfg
      $rep_add "$rep/libbar.git#master"
      $rep_fetch

      $* --output-root $~ libmbar/1.0.0 --output-purge 2>>~%EOE%
        checking out libmbar/1.0.0 (local cache)
        %.+
        distributing libmbar/1.0.0
        checked out libmbar/1.0.0
        EOE

      test -f libmbar-1.0.0/manifest

      $pkg_purge libmbar
    }
  }}

  : fetch-cache
  :
  {{
    # Enable the test-specific fetch caches.
    #
    options_guard = $~/.build2
    +mkdir $options_guard
    +echo '--no-default-options' >=$options_guard/bpkg.options
    +export BPKG_FETCH_CACHE=src
    rep_fetch    += --fetch-cache-path cache
    test.options += --fetch-cache-path cache

    +$cfg_create -d cfg 2>! &cfg/***

    : no-src
    :
    {
      export BPKG_FETCH_CACHE=no-src

      $clone_cfg
      $rep_add "$rep/libbar.git#master"
      $rep_fetch &cache/***

      # Verify that for the first repository fetch we run git-fetch.
      #
      $* -v libbar/1.0.0+1 2>&1 | set out

      sed -n -e 's%^(git.* .*fetch .*origin .*)$%\1%p' <$out >~/.+/
      sed -n -e 's%^(fetching .+style-basic.git in .+ for submodule .extras.)$%\1%p' <$out >~/.+/

      rm -r cfg

      $clone_cfg
      $rep_add "$rep/libbar.git#master"
      $rep_fetch

      # Verify that now, as the repository is cached, we don't run
      # git-fetch.
      #
      $* -v libbar/1.0.0+1 2>&1 | set out

      sed -n -e 's%^(git.* .*fetch .*origin .*)$%\1%p' <$out >:''
      sed -n -e 's%^(fetching .+style-basic.git in .+ for submodule .extras.)$%\1%p' <$out >:''

      $pkg_status libbar >'libbar unpacked 1.0.0+1'

      $pkg_drop libbar
    }

    : src
    :
    {
      pkg_build += -d cfg --yes --no-default-options --fetch-cache-path cache

      $clone_cfg
      $rep_add "$rep/libbar.git#master"
      $rep_fetch &cache/***

      # Verify that for the first repository fetch we run git-fetch.
      #
      $* -v libbar/1.0.0+1 2>&1 | set out

      sed -n -e 's%^(checking out libbar. from .* \(cache, shared src\))$%\1%p'      <$out >~/.+/
      sed -n -e 's%^(git.* .*fetch .*origin .*)$%\1%p'                               <$out >~/.+/
      sed -n -e 's%^(fetching .+style-basic.git in .+ for submodule .extras.)$%\1%p' <$out >~/.+/

      $pkg_status libbar >'libbar unpacked 1.0.0+1'

      # Verify that the source directory is cached.
      #
      test -d cache/src/libbar-1.0.0+1
      test -d cfg/libbar-1.0.0+1 != 0

      # Verify that the unpacked package is buildable.
      #
      $pkg_build libbar 2>>~%EOE%
        %.+
        updated libbar/1.0.0+1
        EOE

      test -d cfg/libbar-1.0.0+1

      rm -r cfg

      $clone_cfg
      $rep_add "$rep/libbar.git#master"
      $rep_fetch

      # Verify that now, as the repository is cached, we don't run
      # git-fetch.
      #
      $* -v libbar/1.0.0+1 2>&1 | set out

      sed -n -e 's%^(checking out libbar. from .* \(cache, shared src\))$%\1%p'      <$out >~/.+/
      sed -n -e 's%^(git.* .*fetch .*origin .*)$%\1%p'                               <$out >:''
      sed -n -e 's%^(fetching .+style-basic.git in .+ for submodule .extras.)$%\1%p' <$out >:''

      $pkg_status libbar >'libbar unpacked 1.0.0+1'

      # Verify that the source directory is cached.
      #
      test -d cache/src/libbar-1.0.0+1
      test -d cfg/libbar-1.0.0+1 != 0

      # Verify that the unpacked package is buildable.
      #
      $pkg_build libbar 2>>~%EOE%
        %.+
        updated libbar/1.0.0+1
        EOE

      test -d cfg/libbar-1.0.0+1

      $pkg_drop libbar
    }
  }}
}}
