Go to the documentation of this file.00001 ##############################################################################
00002 # @file BasisUpdate.cmake
00003 # @brief Implements automatic file udpate feature (deprecated).
00004 #
00005 # @note The automatic file update works well and the implementation is fine.
00006 # However, its use became more and more obsolete during the enhancement
00007 # of BASIS and the development of a more advanced project tool
00008 # (basisproject.py). Moreover, the update of project files during the
00009 # configuration of the build system was controversy.
00010 #
00011 # This file provides functions which implement the automatic file update
00012 # of project files from the corresponding template files which they were
00013 # instantiated from. Instead of the need to manually copy files and/or parts
00014 # of files from the updated project template to each project that was
00015 # instantiated from this particular template, the projects themselves check
00016 # for the availibility of updated template files during the configure step
00017 # of CMake and apply the updates if possible and desired by the user.
00018 # The automatic file update mechanism can be configured to have the user decide
00019 # for each or all files whether an available update may be applied or not.
00020 # Further, updates will only be applied if it is guaranteed that these changes
00021 # can be easily reverted.
00022 #
00023 # The automatic file update feature is only enabled when
00024 #
00025 # 1. The option @c BASIS_UPDATE, which is added by this module, is enabled.
00026 #
00027 # 2. @c BASIS_TEMPLATE_URL is a valid URL to the local root directory or
00028 # repository root directory of the BASIS project template, respectively,
00029 # Note that local directories must be prefixed by "file://".
00030 #
00031 # 3. The Python interpreter "python" was found and thus the variable
00032 # @c PYTHON_EXECUTABLE is set.
00033 #
00034 # 4. The script used to merge the content of the template with the existing
00035 # project files has to be in the same directory as this CMake module.
00036 #
00037 # 5. The project itself has to be under revision control, in particular,
00038 # a valid Subversion working copy. This is required to ensure that changes
00039 # applied during the automatic file udpate can be reverted.
00040 #
00041 # When this module is included, it adds the advanced option @c BASIS_UPDATE_AUTO
00042 # which is @c ON by default. If @c BASIS_UPDATE_AUTO is @c ON, files are updated
00043 # automatically without interacting with the user to get confirmation for file
00044 # update. If a project file contains local modifications or is not under
00045 # revision control, the udpate will not be performed automatically in any case.
00046 # Moreover, files which are listed with their path relative to the project
00047 # source directory in @c BASIS_UPDATE_EXCLUDE are excluded from the automatic file
00048 # update.
00049 #
00050 # Copyright (c) 2011, 2012 University of Pennsylvania. All rights reserved.<br />
00051 # See https://www.cbica.upenn.edu/sbia/software/license.html or COPYING file.
00052 #
00053 # Contact: SBIA Group <sbia-software at uphs.upenn.edu>
00054 #
00055 # @ingroup CMakeTools
00056 ##############################################################################
00057
00058 if (__BASIS_UPDATE_INCLUDED)
00059 return ()
00060 else ()
00061 set (__BASIS_UPDATE_INCLUDED TRUE)
00062 endif ()
00063
00064
00065 # ============================================================================
00066 # options
00067 # ============================================================================
00068
00069 ## @brief Enable/Disable update of files.
00070 option (BASIS_UPDATE "Whether the automatic file update is enabled" "ON")
00071 ## @brief Enable/Disable automatic non-interactive update of files.
00072 option (BASIS_UPDATE_AUTO "Whether files may be updated automatically without confirmation" "ON")
00073
00074 mark_as_advanced (BASIS_UPDATE)
00075 mark_as_advanced (BASIS_UPDATE_AUTO)
00076
00077 # ============================================================================
00078 # required modules
00079 # ============================================================================
00080
00081 include ("${CMAKE_CURRENT_LIST_DIR}/CommonTools.cmake")
00082 include ("${CMAKE_CURRENT_LIST_DIR}/RevisionTools.cmake")
00083
00084 # ============================================================================
00085 # required commands
00086 # ============================================================================
00087
00088 ## @brief Script used to perform the update of a file.
00089 set (BASIS_UPDATE_SCRIPT "${CMAKE_CURRENT_LIST_DIR}/updatefile.py")
00090
00091 # ============================================================================
00092 # initialization
00093 # ============================================================================
00094
00095 ##############################################################################
00096 # @brief Initialize file update and update files already scheduled for update.
00097 #
00098 # This function has to be called before any basis_update() call. It performs
00099 # the update of files already scheduled for updated during a previous CMake
00100 # configure step and for which the user choose to update them by invoking the
00101 # function basis_update_files(). Note that files are only udpated here if the
00102 # interactive mode is enabled or if there are files which could not be updated
00103 # automatically by the last execution of basis_update_finalize(). Otherwise,
00104 # no files are updated by this function. Afterwards the update system is
00105 # initialized for another iteration of CMake's configure step.
00106 #
00107 # Example:
00108 #
00109 # @code
00110 # basis_update_initialize ()
00111 # basis_update (CTestConfig.cmake)
00112 # basis_update_finalize ()
00113 # @endcode
00114 #
00115 # @sa basis_update()
00116 # @sa basis_update_finalize()
00117 # @sa basis_update_files()
00118 #
00119 # @returns Sets @c BASIS_UPDATE_INITIALIZED to indicate the the automatic
00120 # file update feature has been initialized.
00121
00122 function (basis_update_initialize)
00123 # initialize only if not done already
00124 if (BASIS_UPDATE_INITIALIZED)
00125 return ()
00126 endif ()
00127
00128 mark_as_advanced (BASIS_UPDATE_SCRIPT)
00129
00130 # check BASIS_TEMPLATE_URL
00131 set (BASIS_TEMPLATE_URL_VALID 0)
00132
00133 if (BASIS_TEMPLATE_URL MATCHES "file:
00134 string (REGEX REPLACE "file://" "" TMP "${BASIS_TEMPLATE_URL}")
00135 if (IS_DIRECTORY "${TMP}")
00136 set (BASIS_TEMPLATE_URL_VALID 1)
00137 endif ()
00138 elseif (BASIS_TEMPLATE_URL MATCHES "http.*://.*")
00139 basis_svn_get_revision (${BASIS_TEMPLATE_URL} REV)
00140 if (REV)
00141 set (BASIS_TEMPLATE_URL_VALID 1)
00142 endif ()
00143 endif ()
00144
00145 # --------------------------------------------------------------------------
00146 # update enabled
00147 # --------------------------------------------------------------------------
00148
00149 if (
00150 BASIS_UPDATE # 1. update is enabled
00151 AND BASIS_TEMPLATE_URL_VALID # 2. valid template root dir
00152 AND PYTHON_EXECUTABLE # 3. python interpreter found
00153 AND BASIS_UPDATE_SCRIPT # 4. update script found
00154 AND PROJECT_REVISION # 5. project is under revision control
00155 )
00156
00157 # update files which were not updated during last configure run. Instead,
00158 # CMake variables where added which enabled the user to specify the files
00159 # which should be udpated
00160 basis_update_files ()
00161
00162 # --------------------------------------------------------------------------
00163 # update disabled
00164 # --------------------------------------------------------------------------
00165
00166 else ()
00167
00168 if (BASIS_UPDATE)
00169 message ("File update not feasible.")
00170
00171 if (BASIS_VERBOSE)
00172 message ("Variables related to (automatic) file update:
00173
00174 BASIS_UPDATE : ${BASIS_UPDATE}
00175 BASIS_UPDATE_AUTO : ${BASIS_UPDATE_AUTO}
00176 PYTHON_EXECUTABLE : ${PYTHON_EXECUTABLE}
00177 BASIS_UPDATE_SCRIPT : ${BASIS_UPDATE_SCRIPT}
00178 BASIS_TEMPLATE_URL : ${BASIS_TEMPLATE_URL}
00179 PROJECT_REVISION : ${PROJECT_REVISION}
00180 ")
00181 endif ()
00182
00183 if (NOT PYTHON_EXECUTABLE)
00184 message ("=> Python interpreter not found.")
00185 endif ()
00186 if (NOT BASIS_UPDATE_SCRIPT)
00187 message ("=> File update script not found.")
00188 endif ()
00189 if (NOT BASIS_TEMPLATE_URL_VALID)
00190 message ("=> Invalid BASIS_TEMPLATE_URL path.")
00191 endif()
00192 if (NOT PROJECT_REVISION)
00193 message ("=> Project is not under revision control.")
00194 endif ()
00195
00196 message ("Setting BASIS_UPDATE to OFF.")
00197 set (BASIS_UPDATE "OFF" CACHE BOOL "Whether the automatic file update is enabled" FORCE)
00198 endif ()
00199
00200 endif ()
00201
00202 # DO NOT cache this variable
00203 set (BASIS_UPDATE_INITIALIZED 1)
00204 endfunction ()
00205
00206 # ============================================================================
00207 # update
00208 # ============================================================================
00209
00210 ##############################################################################
00211 # @brief Checks for availibility of update and adds files for which an
00212 # updated template exists to BASIS_UPDATE_FILES.
00213 #
00214 # This function retrieves a copy of the latest revision of the corresponding
00215 # template file of the project template from which this project was
00216 # instantiated and caches it in the binary tree. If a cached copy is already
00217 # available, the cached copy is used. Then, it checks whether the template
00218 # contains any updated compared to the current project file, ignoring the
00219 # content of customizable sections. If an udpate is available, the file
00220 # is added to BASIS_UPDATE_FILE. The updates will be applied by either
00221 # basis_update_initialize() if the interactive mode is enabled or by
00222 # basis_update_finalize().
00223 #
00224 # Files which are listed with their path relative to the project source
00225 # directory in BASIS_UPDATE_EXCLUDE are excluded from the automatic file
00226 # update and will hence be skipped by this function.
00227 #
00228 # @sa basis_update_initialize()
00229 # @sa basis_update_finalize()
00230 #
00231 # @param [in] FILENAME Name of project file in current source directory.
00232 #
00233 # @returns Nothing.
00234
00235 function (basis_update FILENAME)
00236 if (NOT BASIS_UPDATE)
00237 return ()
00238 endif ()
00239
00240 # absolute path of project file
00241 set (CUR "${CMAKE_CURRENT_SOURCE_DIR}/${FILENAME}")
00242
00243 # get path of file relative to project source directory
00244 file (RELATIVE_PATH REL "${PROJECT_SOURCE_DIR}" "${CUR}")
00245
00246 # must be AFTER REL was set
00247 if (BASIS_VERBOSE)
00248 message (STATUS "Checking for update of file '${REL}'...")
00249 endif ()
00250
00251 # skip file if excluded from file update
00252 if (BASIS_UPDATE_EXCLUDE)
00253 list (FIND BASIS_UPDATE_EXCLUDE "${CUR}" IDX)
00254 if (IDX EQUAL -1)
00255 list (FIND BASIS_UPDATE_EXCLUDE "${REL}" IDX)
00256 endif ()
00257 if (NOT IDX EQUAL -1)
00258 if (BASIS_VERBOSE)
00259 message (STATUS "Checking for update of file '${REL}'... - excluded")
00260 endif ()
00261 return ()
00262 endif ()
00263 endif ()
00264
00265 # skip file if it is not under revision control
00266 if (EXISTS "${CUR}")
00267 basis_svn_get_last_changed_revision ("${CUR}" CURREV)
00268
00269 if (CURREV EQUAL 0)
00270 if (BASIS_VERBOSE)
00271 message (STATUS "Checking for update of file '${REL}'... - file unversioned")
00272 endif ()
00273
00274 return ()
00275 endif ()
00276 endif ()
00277
00278 # retrieve template file
00279 basis_update_cached_template ("${REL}" TMP) # file name of cached template file
00280 basis_update_template ("${REL}" "${TMP}" RETVAL) # update cached template file
00281
00282 if (NOT RETVAL)
00283 message (STATUS "Checking for update of file '${REL}'... - template missing")
00284 return ()
00285 endif ()
00286
00287 # get currently cached list of files in BASIS_UPDATE_FILES
00288 set (FILES ${BASIS_UPDATE_FILES})
00289
00290 # --------------------------------------------------------------------------
00291 # check if update of existing project file is available
00292 # --------------------------------------------------------------------------
00293
00294 if (EXISTS "${CUR}")
00295 execute_process (
00296 COMMAND
00297 "${PYTHON_EXECUTABLE}" "${BASIS_UPDATE_SCRIPT}" -i "${CUR}" -t "${TMP}"
00298 RESULT_VARIABLE
00299 RETVAL
00300 OUTPUT_QUIET
00301 ERROR_QUIET
00302 )
00303
00304 if (RETVAL EQUAL 0)
00305 list (APPEND FILES "${REL}")
00306 elseif (RETVAL EQUAL 2)
00307
00308 if (FILES)
00309 list (REMOVE_ITEM FILES "${REL}")
00310 endif ()
00311
00312 basis_update_option ("${REL}" OPT)
00313
00314 if (DEFINED ${OPT})
00315 set (${OPT} "" CACHE INTERNAL "Unused option." FORCE)
00316 endif ()
00317 endif ()
00318
00319 if (BASIS_VERBOSE)
00320 if (RETVAL EQUAL 0)
00321 message (STATUS "Checking for update of file '${REL}'... - update available")
00322 elseif (RETVAL EQUAL 2)
00323 message (STATUS "Checking for update of file '${REL}'... - up-to-date")
00324 else ()
00325 message (STATUS "Checking for update of file '${REL}'... - failed")
00326 endif ()
00327 endif ()
00328
00329 # --------------------------------------------------------------------------
00330 # new files added to template
00331 # --------------------------------------------------------------------------
00332
00333 else ()
00334
00335 list (APPEND FILES "${REL}")
00336
00337 if (BASIS_VERBOSE)
00338 message (STATUS "Checking for update of file '${REL}'... - file missing")
00339 endif ()
00340
00341 endif ()
00342
00343 # update cached variable BASIS_UPDATE_FILES
00344 set (BASIS_UPDATE_FILES ${FILES} CACHE INTERNAL "Files to be updated." FORCE)
00345 endfunction ()
00346
00347 # ============================================================================
00348 # finalization
00349 # ============================================================================
00350
00351 ##############################################################################
00352 # @brief Adds file update options for user interaction or performs
00353 # file update immediately if quiet update enabled.
00354 #
00355 # @sa basis_update()
00356 # @sa basis_update_initialize()
00357 # @sa basis_update_finalize()
00358 #
00359 # @returns Nothing.
00360
00361 function (basis_update_finalize)
00362 if (NOT BASIS_UPDATE)
00363 return ()
00364 endif ()
00365
00366 set (FILES ${BASIS_UPDATE_FILES})
00367
00368 if (FILES)
00369 list (REMOVE_DUPLICATES FILES)
00370 endif ()
00371
00372 # iterate over files added by basis_update ()
00373 foreach (REL ${FILES})
00374
00375 # absolute path of project file
00376 set (CUR "${PROJECT_SOURCE_DIR}/${REL}")
00377
00378 # name of cached template file
00379 basis_update_cached_template ("${REL}" TMP)
00380
00381 # ------------------------------------------------------------------------
00382 # project file exists
00383 # ------------------------------------------------------------------------
00384
00385 if (EXISTS "${CUR}")
00386
00387 # check if it is under revision control and whether it has local modifications
00388 if (EXISTS "${CUR}")
00389 basis_svn_get_last_changed_revision (${CUR} CURREV)
00390 basis_svn_status (${CUR} CURSTATUS)
00391 endif ()
00392
00393 basis_update_option ("${REL}" OPT) # name of file update option
00394
00395 # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
00396 # quietly update file w/o user interaction
00397 # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
00398
00399 if (
00400 BASIS_UPDATE_AUTO # 1. option BASIS_UPDATE_AUTO is ON
00401 AND CURREV GREATER 0 # 2. project file is under revision control
00402 AND "${CURSTATUS}" STREQUAL "" # 3. project file has no local modifications
00403 )
00404 if (BASIS_VERBOSE)
00405 message (STATUS "Updating file '${REL}'...")
00406 endif ()
00407
00408 execute_process (
00409 COMMAND
00410 "${PYTHON_EXECUTABLE}" "${BASIS_UPDATE_SCRIPT}" -f -i "${CUR}" -t "${TMP}" -o "${CUR}"
00411 RESULT_VARIABLE
00412 RETVAL
00413 OUTPUT_QUIET
00414 ERROR_QUIET
00415 )
00416
00417 if (RETVAL EQUAL 0 OR RETVAL EQUAL 2)
00418 list (REMOVE_ITEM FILES "${REL}")
00419 set (${OPT} "" CACHE INTERNAL "Unused option." FORCE)
00420 endif ()
00421
00422 if (RETVAL EQUAL 0)
00423 message ("Updated file '${REL}'")
00424 elseif (NOT RETVAL EQUAL 2)
00425 message ("Failed to update file '${REL}'")
00426 endif ()
00427
00428 if (BASIS_VERBOSE)
00429 if (RETVAL EQUAL 0)
00430 message (STATUS "Updating file '${REL}'... - done")
00431 elseif (RETVAL EQUAL 2)
00432 message (STATUS "Updating file '${REL}'... - up-to-date")
00433 else ()
00434 message (STATUS "Updating file '${REL}'... - failed")
00435 endif ()
00436 endif ()
00437
00438 # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
00439 # add file update option (if not present yet)
00440 # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
00441
00442 else ()
00443
00444 if ("${${OPT}}" STREQUAL "")
00445 # add option which user can modify to force update of file
00446 set (${OPT} "OFF" CACHE BOOL "Whether file '${REL}' should be updated." FORCE)
00447 # add BASIS_UPDATE_ALL option if not present
00448 if ("${UPDATE_ALL}" STREQUAL "")
00449 set (UPDATE_ALL "OFF" CACHE BOOL "Whether all files should be updated." FORCE)
00450 endif ()
00451 endif ()
00452
00453 # inform user that file update is available
00454 message ("Update of file '${REL}' available.\nSet UPDATE_ALL or ${OPT} to ON if changes should be applied.")
00455
00456 endif ()
00457
00458 # ----------------------------------------------------------------------
00459 # project file non existent
00460 # ----------------------------------------------------------------------
00461
00462 else ()
00463
00464 if (BASIS_VERBOSE)
00465 message (STATUS "Adding file '${REL}'...")
00466 endif ()
00467
00468 configure_file ("${TMP}" "${CUR}" COPYONLY)
00469
00470 list (REMOVE_ITEM FILES "${REL}")
00471 set (${OPT} "" CACHE INTERNAL "Unused option." FORCE)
00472
00473 message ("Added file '${REL}'. Do not forget to add it to the repository!")
00474
00475 if (BASIS_VERBOSE)
00476 message (STATUS "Adding file '${REL}'... - done")
00477 endif ()
00478
00479 endif ()
00480
00481 endforeach ()
00482
00483 if (NOT FILES)
00484 set (UPDATE_ALL "" CACHE INTERNAL "Unused option." FORCE)
00485 endif ()
00486
00487 set (BASIS_UPDATE_FILES ${FILES} CACHE INTERNAL "Files to be updated." FORCE)
00488 endfunction ()
00489
00490 # ============================================================================
00491 # helpers
00492 # ============================================================================
00493
00494 # ----------------------------------------------------------------------------
00495 # common helpers
00496 # ----------------------------------------------------------------------------
00497
00498 ##############################################################################
00499 # @brief Get name of file update option.
00500 #
00501 # The CMake variable name returned by this function is used as file update
00502 # option which enables the user to select which files should be udpated.
00503 #
00504 # @sa basis_update_finalize()
00505 # @sa basis_update_files()
00506 #
00507 # @param [in] REL Path of project file relative to project source directory.
00508 # @param [out] OPTION_NAME Name of file update option.
00509 #
00510 # @returns Sets @p OPTION_NAME to the name of the CMake option variable.
00511
00512 function (basis_update_option REL OPTION_NAME)
00513 set (TMP "${REL}")
00514 string (REGEX REPLACE "\\.|\\\\|/|-" "_" TMP ${TMP})
00515 set (${OPTION_NAME} "UPDATE_${TMP}" PARENT_SCOPE)
00516 endfunction ()
00517
00518 ##############################################################################
00519 # @brief Get filename of cached template file.
00520 #
00521 # @param [in] REL Path of project file relative to project source directory.
00522 # @param [out] TEMPLATE Absolute path of cached template file in binary tree
00523 # of project.
00524 #
00525 # @returns Sets @p TEMPLATE to the full path of the updated template file.
00526
00527 function (basis_update_cached_template REL TEMPLATE)
00528 # URL of template file
00529 set (SRC "${BASIS_TEMPLATE_URL}/${REL}")
00530
00531 # get revision of template file. If no revision number can be determined,
00532 # we either did not find the svn client or the file referenced by SRC
00533 # is not a repository. However, if it is a working copy, we will still
00534 # get a revision number. Thus, we then need to check if SRC is a URL
00535 # starting with 'https://sbia-svn' or not (see below).
00536 basis_svn_get_last_changed_revision ("${SRC}" REV)
00537
00538 if (REV GREATER 0)
00539 basis_svn_status ("${SRC}" STATUS)
00540 if (NOT "${STATUS}" STREQUAL "")
00541 set (REV "0") # under revision control, but locally modified
00542 endif ()
00543 else ()
00544 set (REV "-") # not under revision control (or non-existent)
00545 endif ()
00546
00547 # file name of cached template file in binary tree of project
00548 set (${TEMPLATE} "${PROJECT_BINARY_DIR}/${REL}.rev${REV}" PARENT_SCOPE)
00549 endfunction ()
00550
00551 # ----------------------------------------------------------------------------
00552 # update helpers
00553 # ----------------------------------------------------------------------------
00554
00555 ##############################################################################
00556 # @brief Removes cached template files from binary tree.
00557 #
00558 # This function is used by basis_update_template() to remove cached template
00559 # copies of a particular file in the binary tree when no longer needed.
00560 #
00561 # @sa basis_update_template()
00562 #
00563 # @param [in] REL Path of the project file whose template copies shall be
00564 # removed relative to the project's source directory.
00565 # @param [in] ARGN Absolute paths of cached template files to preserve.
00566 #
00567 # @returns Nothing.
00568
00569 function (basis_update_clear REL)
00570 # collect all cached template files
00571 file (GLOB FILES "${PROJECT_BINARY_DIR}/${REL}.rev*")
00572 # remove files which are to be preserved
00573 if (FILES)
00574 foreach (ARG ${ARGN})
00575 list (REMOVE_ITEM FILES ${ARG})
00576 endforeach ()
00577 endif ()
00578 # remove files
00579 if (FILES)
00580 file (REMOVE ${FILES})
00581 endif ()
00582 endfunction ()
00583
00584 ##############################################################################
00585 # @brief Retrieves latest revision of template file.
00586 #
00587 # @param [in] REL Path of project/template file relative to project source tree.
00588 # @param [in] TEMPLATE Absolute path of cached template file in binary tree of project.
00589 # @param [out] RETVAL Boolean variable which indicates success or failure.
00590 #
00591 # @returns Sets @p RETVAL either to 1 or 0 whether or not the update was
00592 # successful or not, respectively.
00593
00594 function (basis_update_template REL TEMPLATE RETVAL)
00595
00596 # URL of template file
00597 set (SRC "${BASIS_TEMPLATE_URL}/${REL}")
00598
00599 # if template file is not under revision control or has local modifications
00600 # we cannot use caching as there is no unique revision number assigned
00601 if (TEMPLATE MATCHES ".*\\.rev[0|-]")
00602
00603 # remove previously exported/downloaded template files
00604 basis_update_clear ("${REL}")
00605
00606 # download template file from non-revision controlled template
00607 file (DOWNLOAD "${SRC}" "${TEMPLATE}" TIMEOUT 30 STATUS RET)
00608 list (GET RET 0 RET)
00609
00610 # if cached file not available, retrieve it from repository or working copy
00611 elseif (NOT EXISTS "${TEMPLATE}")
00612
00613 # remove previously exported/downloaded revisions
00614 basis_update_clear ("${REL}")
00615
00616 # if template URL is SVN repository, export file using SVN client
00617 if ("${SRC}" MATCHES "^https:
00618 execute_process (
00619 COMMAND "${Subversion_SVN_EXECUTABLE}" export "${SRC}" "${TEMPLATE}"
00620 TIMEOUT 30
00621 RESULT_VARIABLE RET
00622 OUTPUT_QUIET
00623 ERROR_QUIET
00624 )
00625 # otherwise, download file
00626 else ()
00627 file (DOWNLOAD "${SRC}" "${TEMPLATE}" TIMEOUT 30 STATUS RET)
00628 list (GET RET 0 RET)
00629 endif ()
00630 else ()
00631 basis_update_clear ("${REL}" "${TEMPLATE}")
00632 set (RET 0)
00633 endif ()
00634
00635 # return value
00636 if (RET EQUAL 0)
00637 set (${RETVAL} 1 PARENT_SCOPE)
00638 else ()
00639 set (${RETVAL} 0 PARENT_SCOPE)
00640 endif ()
00641 endfunction ()
00642
00643 ##############################################################################
00644 # @brief Update files listed in BASIS_UPDATE_FILES for which file
00645 # update option exists and is ON or UPDATE_ALL is ON.
00646 #
00647 # This function attempts to update all files in BASIS_UPDATE_FILES
00648 # whose file update option is ON. If the option UPDATE_ALL is ON,
00649 # the file update options of individual files are ignored and all files
00650 # are updated. It is called by basis_update_initialize().
00651 #
00652 # The list BASIS_UPDATE_FILES is populated by the function basis_update()
00653 # and the file update options for the listed files are added by
00654 # basis_update_finalize() if BASIS_UPDATE_QUIET is OFF. Otherwise,
00655 # the files are updated directly by basis_update_finalize() if possible.
00656 #
00657 # @sa basis_update_initialize()
00658 # @sa basis_update_finalize()
00659 #
00660 # @returns Nothing.
00661
00662 function (basis_update_files)
00663 if (NOT BASIS_UPDATE)
00664 return ()
00665 endif ()
00666
00667 set (FILES ${BASIS_UPDATE_FILES})
00668
00669 if (FILES)
00670 list (REMOVE_DUPLICATES FILES)
00671 endif ()
00672
00673 foreach (REL ${FILES})
00674
00675 # absolute path of project file
00676 set (CUR "${PROJECT_SOURCE_DIR}/${REL}")
00677
00678 # if project file exists, check if it is under revision control and
00679 # whether it has local modifications
00680 if (EXISTS "${CUR}")
00681 basis_svn_status (${CUR} CURSTATUS)
00682 else ()
00683 set (CURSTATUS "")
00684 endif ()
00685
00686 # get name of cached template file
00687 basis_update_cached_template ("${REL}" TMP)
00688
00689 # if cached template file exists...
00690 if (EXISTS "${TMP}")
00691
00692 basis_update_option ("${REL}" OPT) # name of file update option
00693
00694 # ...and file update option is ON
00695 if ("${${OPT}}" STREQUAL "ON" OR "${UPDATE_ALL}" STREQUAL "ON")
00696
00697 if (BASIS_VERBOSE)
00698 message (STATUS "Updating file '${REL}'...")
00699 endif ()
00700
00701 # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
00702 # project file has local modifications
00703 # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
00704
00705 if (NOT "${CURSTATUS}" STREQUAL "")
00706
00707 message ("File '${REL}' has local modifications. Modifications must be committed or reverted before file can be updated.")
00708
00709 if ("${${OPT}}" STREQUAL "ON")
00710 message ("Setting ${OPT} to OFF.")
00711 set (${OPT} "OFF" CACHE BOOL "Whether file '${REL}' should be updated." FORCE)
00712 endif ()
00713
00714 if (BASIS_VERBOSE)
00715 message (STATUS "Updating file '${REL}'... - failed")
00716 endif ()
00717
00718 # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
00719 # project file has NO local modifications
00720 # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
00721
00722 else ()
00723
00724 execute_process (
00725 COMMAND
00726 "${PYTHON_EXECUTABLE}" "${BASIS_UPDATE_SCRIPT}" -f -i "${CUR}" -t "${TMP}" -o "${CUR}"
00727 RESULT_VARIABLE
00728 RETVAL
00729 OUTPUT_QUIET
00730 ERROR_QUIET
00731 )
00732
00733 if (RETVAL EQUAL 0 OR RETVAL EQUAL 2)
00734 list (REMOVE_ITEM FILES "${REL}")
00735 set (${OPT} "" CACHE INTERNAL "Unused option." FORCE)
00736 endif ()
00737
00738 if (RETVAL EQUAL 0)
00739 message ("Updated file '${REL}'")
00740 elseif (NOT RETVAL EQUAL 2)
00741 message ("Failed to update file '${REL}'")
00742 endif ()
00743
00744 if (BASIS_VERBOSE)
00745 if (RETVAL EQUAL 0)
00746 message (STATUS "Updating file '${REL}'... - done")
00747 elseif (RETVAL EQUAL 2)
00748 message (STATUS "Updating file '${REL}'... - up-to-date")
00749 else ()
00750 message (STATUS "Updating file '${REL}'... - failed")
00751 endif ()
00752 endif ()
00753
00754 endif ()
00755 endif ()
00756 endif ()
00757
00758 endforeach ()
00759
00760 set (BASIS_UPDATE_FILES ${FILES} CACHE INTERNAL "Files to be updated." FORCE)
00761
00762 # reset option UPDATE_ALL
00763 if (FILES)
00764 if ("${UPDATE_ALL}" STREQUAL "ON")
00765 message ("Setting UPDATE_ALL to OFF.")
00766 set (UPDATE_ALL "OFF" CACHE BOOL "Whether all files should be updated." FORCE)
00767 endif ()
00768 else ()
00769 set (UPDATE_ALL "" CACHE INTERNAL "Unused option." FORCE)
00770 endif ()
00771 endfunction ()