# This script drives creation of a Subversion repository and checks
# that CTest can update from it.

#-----------------------------------------------------------------------------
# Test in a directory next to this script.
get_filename_component(TOP "${CMAKE_CURRENT_LIST_FILE}" PATH)
set(TOP "${TOP}/@CTestUpdateSVN_DIR@")
set(UPDATE_GLOBAL_ELEMENTS SVNPath)

# Include code common to all update tests.
include("@CMAKE_CURRENT_SOURCE_DIR@/CTestUpdateCommon.cmake")

#-----------------------------------------------------------------------------
# Report subversion tools in use.
message("Using subversion tools:")
set(SVN "@Subversion_SVN_EXECUTABLE@")
set(SVNADMIN "@Subversion_SVNADMIN_EXECUTABLE@")
message(" svn      = ${SVN}")
message(" svnadmin = ${SVNADMIN}")

# Isolate svn test operations from the user configuration.
file(MAKE_DIRECTORY ${TOP}/config)
set(SVNCMD ${SVN} --config-dir ${TOP}/config)
set(SVNUSER --username "test author" --non-interactive)

#-----------------------------------------------------------------------------
# Initialize the testing directory.
message("Creating test directory...")
init_testing()

#-----------------------------------------------------------------------------
# Create the repository.
message("Creating repository...")
file(MAKE_DIRECTORY ${TOP}/repo)
run_child(
  COMMAND ${SVNADMIN} create --config-dir ${TOP}/config ${TOP}/repo
  )
set(REPO file:///${TOP}/repo/trunk)

#-----------------------------------------------------------------------------
# Import initial content into the repository.
message("Importing content...")
create_content(import)

# Import the content into the repository.
run_child(
  WORKING_DIRECTORY ${TOP}/import
  COMMAND ${SVNCMD} import ${SVNUSER} -m "Initial content" . "${REPO}"
  )

#-----------------------------------------------------------------------------
# Create a working tree.
message("Checking out revision 1...")
run_child(
  WORKING_DIRECTORY ${TOP}
  COMMAND ${SVNCMD} co ${SVNUSER} ${REPO} user-source
  )

#-----------------------------------------------------------------------------
# Make changes in the working tree.
message("Changing content...")
update_content(user-source files_added files_removed dirs_added)
if(dirs_added)
  run_child(
    WORKING_DIRECTORY ${TOP}/user-source
    COMMAND ${SVNCMD} add ${dirs_added}
    )
endif(dirs_added)
run_child(
  WORKING_DIRECTORY ${TOP}/user-source
  COMMAND ${SVNCMD} add ${files_added}
  )
run_child(
  WORKING_DIRECTORY ${TOP}/user-source
  COMMAND ${SVNCMD} rm ${files_removed}
  )

#-----------------------------------------------------------------------------
# Commit the changes to the repository.
message("Committing revision 2...")
run_child(
  WORKING_DIRECTORY ${TOP}/user-source
  COMMAND ${SVNCMD} commit -m "Changed content"
  )

#-----------------------------------------------------------------------------
# Make changes in the working tree.
message("Changing content again...")
change_content(user-source)

#-----------------------------------------------------------------------------
# Commit the changes to the repository.
message("Committing revision 3...")
run_child(
  WORKING_DIRECTORY ${TOP}/user-source
  COMMAND ${SVNCMD} commit -m "Changed content again"
  )

#-----------------------------------------------------------------------------
# Go back to before the changes so we can test updating.
message("Backing up to revision 1...")
run_child(
  WORKING_DIRECTORY ${TOP}/user-source
  COMMAND ${SVNCMD} up -r1
  )

# Create a modified file.
message("Modifying locally...")
modify_content(user-source)

#-----------------------------------------------------------------------------
# Test updating the user work directory with the command-line interface.
message("Running CTest Dashboard Command Line...")

# Create the user build tree.
create_build_tree(user-source user-binary)
file(APPEND ${TOP}/user-binary/CTestConfiguration.ini
  "# SVN command configuration
SVNCommand: ${SVN}
SVNUpdateOptions: --config-dir \"${TOP}/config\"
")

# Run the dashboard command line interface.
run_dashboard_command_line(user-binary)

#-----------------------------------------------------------------------------
# Test initial checkout and update with a dashboard script.
message("Running CTest Dashboard Script...")

create_dashboard_script(dashboard.cmake
  "# Subversion command configuration
set(CTEST_SVN_COMMAND \"${SVN}\")
set(CTEST_SVN_UPDATE_OPTIONS
  \"--config-dir \\\"\${CTEST_DASHBOARD_ROOT}/config\\\"\")
set(CTEST_CHECKOUT_COMMAND
  \"\\\"\${CTEST_SVN_COMMAND}\\\" co -r1 \\\"${REPO}\\\" dash-source\")
")

# Run the dashboard script with CTest.
run_dashboard_script(dashboard.cmake)
