Browse Source

Merge topic 'file_cmd_touch'

e78e24f6 Replaces execute_process calls to touch files with file(TOUCH) calls
602988e1 Adds file(TOUCH) and file(TOUCH_NOCREATE) sub-commands

Acked-by: Kitware Robot <[email protected]>
Merge-request: !1705
Brad King 7 years ago
parent
commit
524696ec10

+ 17 - 0
Help/command/file.rst

@@ -283,6 +283,23 @@ If neither ``TLS`` option is given CMake will check variables
 
 ------------------------------------------------------------------------------
 
+::
+
+  file(TOUCH [<files>...])
+  file(TOUCH_NOCREATE [<files>...])
+
+Create a file with no content if it does not yet exist. If the file already
+exists, its access and/or modification will be updated to the time when the
+function call is executed.
+
+Use TOUCH_NOCREATE to touch a file if it exists but not create it. If a file
+does not exist it will be silently ignored.
+
+With TOUCH and TOUCH_NOCREATE the contents of an existing file will not be
+modified.
+
+------------------------------------------------------------------------------
+
 ::
 
   file(TIMESTAMP <filename> <variable> [<format>] [UTC])

+ 6 - 0
Help/release/dev/file_cmd_touch.rst

@@ -0,0 +1,6 @@
+file_cmd_touch
+------------------
+
+* The :command:`file(TOUCH)` and :command:`file(TOUCH_NOCREATE)` commands
+  were added to expose TOUCH functionality without having to use CMake's
+  command-line tool mode with :command:`execute_process`.

+ 1 - 1
Modules/ExternalData.cmake

@@ -1133,7 +1133,7 @@ if("${ExternalData_ACTION}" STREQUAL "fetch")
 
   if(file_up_to_date)
     # Touch the file to convince the build system it is up to date.
-    execute_process(COMMAND "${CMAKE_COMMAND}" -E touch "${file}")
+    file(TOUCH "${file}")
   else()
     _ExternalData_link_or_copy("${obj}" "${file}")
   endif()

+ 38 - 0
Source/cmFileCommand.cxx

@@ -160,6 +160,12 @@ bool cmFileCommand::InitialPass(std::vector<std::string> const& args,
   if (subCommand == "TO_NATIVE_PATH") {
     return this->HandleCMakePathCommand(args, true);
   }
+  if (subCommand == "TOUCH") {
+    return this->HandleTouchCommand(args, true);
+  }
+  if (subCommand == "TOUCH_NOCREATE") {
+    return this->HandleTouchCommand(args, false);
+  }
   if (subCommand == "TIMESTAMP") {
     return this->HandleTimestampCommand(args);
   }
@@ -905,6 +911,38 @@ bool cmFileCommand::HandleMakeDirectoryCommand(
   return true;
 }
 
+bool cmFileCommand::HandleTouchCommand(std::vector<std::string> const& args,
+                                       bool create)
+{
+  // File command has at least one argument
+  assert(args.size() > 1);
+
+  std::vector<std::string>::const_iterator i = args.begin();
+
+  i++; // Get rid of subcommand
+
+  for (; i != args.end(); ++i) {
+    std::string tfile = *i;
+    if (!cmsys::SystemTools::FileIsFullPath(tfile)) {
+      tfile = this->Makefile->GetCurrentSourceDirectory();
+      tfile += "/" + *i;
+    }
+    if (!this->Makefile->CanIWriteThisFile(tfile)) {
+      std::string e =
+        "attempted to touch a file: " + tfile + " in a source directory.";
+      this->SetError(e);
+      cmSystemTools::SetFatalErrorOccured();
+      return false;
+    }
+    if (!cmSystemTools::Touch(tfile, create)) {
+      std::string error = "problem touching file: " + tfile;
+      this->SetError(error);
+      return false;
+    }
+  }
+  return true;
+}
+
 bool cmFileCommand::HandleDifferentCommand(
   std::vector<std::string> const& args)
 {

+ 1 - 0
Source/cmFileCommand.h

@@ -39,6 +39,7 @@ protected:
   bool HandleHashCommand(std::vector<std::string> const& args);
   bool HandleStringsCommand(std::vector<std::string> const& args);
   bool HandleGlobCommand(std::vector<std::string> const& args, bool recurse);
+  bool HandleTouchCommand(std::vector<std::string> const& args, bool create);
   bool HandleMakeDirectoryCommand(std::vector<std::string> const& args);
 
   bool HandleRelativePathCommand(std::vector<std::string> const& args);

+ 0 - 2
Source/cmcmd.cxx

@@ -689,8 +689,6 @@ int cmcmd::ExecuteCMakeCommand(std::vector<std::string>& args)
     // Touch file
     if (args[1] == "touch_nocreate" && args.size() > 2) {
       for (std::string::size_type cc = 2; cc < args.size(); cc++) {
-        // Complain if the file could not be removed, still exists,
-        // and the -f option was not given.
         if (!cmSystemTools::Touch(args[cc], false)) {
           return 1;
         }

+ 2 - 4
Tests/QtAutogen/RerunRccDepends/CMakeLists.txt

@@ -45,8 +45,7 @@ file(TIMESTAMP "${rccDepBinGen}" rdGenBefore "${timeformat}")
 # - Change a resource files listed in the .qrc file
 # - Rebuild
 execute_process(COMMAND "${CMAKE_COMMAND}" -E sleep 1)
-execute_process(COMMAND "${CMAKE_COMMAND}" -E touch "${rccDepBD}/resPlain/input.txt")
-execute_process(COMMAND "${CMAKE_COMMAND}" -E touch "${rccDepBD}/resGen/input.txt")
+file(TOUCH "${rccDepBD}/resPlain/input.txt" "${rccDepBD}/resGen/input.txt")
 execute_process(COMMAND "${CMAKE_COMMAND}" --build . WORKING_DIRECTORY "${rccDepBD}" RESULT_VARIABLE result)
 if (result)
   message(SEND_ERROR "Second build of rccDepends failed.")
@@ -97,8 +96,7 @@ file(TIMESTAMP "${rccDepBinGen}" rdGenBefore "${timeformat}")
 # - Change a newly added resource files listed in the .qrc file
 # - Rebuild
 execute_process(COMMAND "${CMAKE_COMMAND}" -E sleep 1)
-execute_process(COMMAND "${CMAKE_COMMAND}" -E touch "${rccDepBD}/resPlain/inputAdded.txt")
-execute_process(COMMAND "${CMAKE_COMMAND}" -E touch "${rccDepBD}/resGen/inputAdded.txt")
+file(TOUCH "${rccDepBD}/resPlain/inputAdded.txt" "${rccDepBD}/resGen/inputAdded.txt")
 execute_process(COMMAND "${CMAKE_COMMAND}" --build . WORKING_DIRECTORY "${rccDepBD}" RESULT_VARIABLE result)
 if (result)
   message(SEND_ERROR "Fourth build of rccDepends failed.")

+ 1 - 2
Tests/RunCMake/VS10Project/VsCSharpCustomTags.cmake

@@ -16,8 +16,7 @@ set(fileNames)
 foreach(e ${fileExtensions})
   set(currentFile "${CMAKE_CURRENT_BINARY_DIR}/foo.${e}")
   list(APPEND fileNames ${currentFile})
-  execute_process(COMMAND ${CMAKE_COMMAND} -E touch
-    "${currentFile}")
+  file(TOUCH "${currentFile}")
   string(TOUPPER ${e} eUC)
   set_source_files_properties("${currentFile}"
     PROPERTIES

+ 3 - 0
Tests/RunCMake/file/RunCMakeTest.cmake

@@ -5,6 +5,9 @@ run_cmake(DOWNLOAD-unused-argument)
 run_cmake(DOWNLOAD-httpheader-not-set)
 run_cmake(DOWNLOAD-netrc-bad)
 run_cmake(DOWNLOAD-pass-not-set)
+run_cmake(TOUCH)
+run_cmake(TOUCH-error-in-source-directory)
+run_cmake(TOUCH-error-missing-directory)
 run_cmake(UPLOAD-unused-argument)
 run_cmake(UPLOAD-httpheader-not-set)
 run_cmake(UPLOAD-netrc-bad)

+ 1 - 0
Tests/RunCMake/file/TOUCH-error-in-source-directory-result.txt

@@ -0,0 +1 @@
+1

+ 1 - 0
Tests/RunCMake/file/TOUCH-error-in-source-directory-stderr.txt

@@ -0,0 +1 @@
+.*file attempted to touch a file:

+ 2 - 0
Tests/RunCMake/file/TOUCH-error-in-source-directory.cmake

@@ -0,0 +1,2 @@
+set(CMAKE_DISABLE_SOURCE_CHANGES ON)
+file(TOUCH "${CMAKE_CURRENT_SOURCE_DIR}/touch_test")

+ 1 - 0
Tests/RunCMake/file/TOUCH-error-missing-directory-result.txt

@@ -0,0 +1 @@
+1

+ 1 - 0
Tests/RunCMake/file/TOUCH-error-missing-directory-stderr.txt

@@ -0,0 +1 @@
+.*file problem touching file:

+ 1 - 0
Tests/RunCMake/file/TOUCH-error-missing-directory.cmake

@@ -0,0 +1 @@
+file(TOUCH "${CMAKE_CURRENT_BINARY_DIR}/missing/directory/file.to-touch")

+ 1 - 0
Tests/RunCMake/file/TOUCH-result.txt

@@ -0,0 +1 @@
+1

+ 9 - 0
Tests/RunCMake/file/TOUCH-stderr.txt

@@ -0,0 +1,9 @@
+^CMake Error at TOUCH\.cmake:[0-9]+ \(file\):
+  file must be called with at least two arguments\.
+Call Stack \(most recent call first\):
+  CMakeLists\.txt:[0-9]+ \(include\)
++
+CMake Error at TOUCH\.cmake:[0-9]+ \(file\):
+  file must be called with at least two arguments\.
+Call Stack \(most recent call first\):
+  CMakeLists\.txt:[0-9]+ \(include\)

+ 16 - 0
Tests/RunCMake/file/TOUCH.cmake

@@ -0,0 +1,16 @@
+set(file "${CMAKE_CURRENT_BINARY_DIR}/file-to-touch")
+
+file(REMOVE "${file}")
+file(TOUCH_NOCREATE "${file}")
+if(EXISTS "${file}")
+  message(FATAL_ERROR "error: TOUCH_NOCREATE created a file!")
+endif()
+
+file(TOUCH "${file}")
+if(NOT EXISTS "${file}")
+  message(FATAL_ERROR "error: TOUCH did not create a file!")
+endif()
+file(REMOVE "${file}")
+
+file(TOUCH)
+file(TOUCH_NOCREATE)