Browse Source

Merge topic 'fileapi-config-dir'

1df94443fe fileapi: Add support for user-wide queries
a991a5019b Tests: Isolate test suite from user-wide configuration
320b81847d Tests: Remove unused cvs anonymous access credentials

Acked-by: Kitware Robot <[email protected]>
Tested-by: buildbot <[email protected]>
Merge-request: !9744
Brad King 1 year ago
parent
commit
fe63f15383

+ 18 - 0
Help/envvar/CMAKE_CONFIG_DIR.rst

@@ -0,0 +1,18 @@
+CMAKE_CONFIG_DIR
+----------------
+
+.. versionadded:: 3.31
+
+.. include:: ENV_VAR.txt
+
+Specify a CMake user-wide configuration directory for
+:manual:`cmake-file-api(7)` queries.
+
+If this environment variable is not set, the default user-wide
+configuration directory is platform-specific:
+
+- Windows: ``%LOCALAPPDATA%\CMake``
+- macOS: ``$XDG_CONFIG_HOME/CMake`` if set, otherwise
+  ``$HOME/Library/Application Support/CMake``
+- Linux/Other: ``$XDG_CONFIG_HOME/cmake`` if set, otherwise
+  ``$HOME/.config/cmake``

+ 2 - 1
Help/manual/cmake-env-variables.7.rst

@@ -43,8 +43,9 @@ Environment Variables that Control the Build
    /envvar/CMAKE_BUILD_PARALLEL_LEVEL
    /envvar/CMAKE_BUILD_TYPE
    /envvar/CMAKE_COLOR_DIAGNOSTICS
-   /envvar/CMAKE_CONFIGURATION_TYPES
+   /envvar/CMAKE_CONFIG_DIR
    /envvar/CMAKE_CONFIG_TYPE
+   /envvar/CMAKE_CONFIGURATION_TYPES
    /envvar/CMAKE_CROSSCOMPILING_EMULATOR
    /envvar/CMAKE_EXPORT_COMPILE_COMMANDS
    /envvar/CMAKE_GENERATOR

+ 4 - 0
Help/manual/cmake-file-api.7.rst

@@ -50,6 +50,10 @@ It has the following subdirectories:
   Clients may optionally create the ``reply/`` directory at any time
   and monitor it for the appearance of a new reply index file.
 
+.. versionadded:: 3.31
+  Users can add query files to ``api/v1/query`` inside the
+  :envvar:`CMAKE_CONFIG_DIR` to create user-wide queries for all CMake projects.
+
 v1 Shared Stateless Query Files
 -------------------------------
 

+ 8 - 0
Help/manual/cmake.1.rst

@@ -266,6 +266,14 @@ Options
  from the top of a binary tree for a CMake project it will dump
  additional information such as the cache, log files etc.
 
+.. option:: --print-config-dir
+
+ .. versionadded:: 3.31
+
+ Print CMake config directory for user-wide FileAPI queries.
+
+ See :envvar:`CMAKE_CONFIG_DIR` for more details.
+
 .. option:: --log-level=<level>
 
  .. versionadded:: 3.16

+ 21 - 2
Source/cmFileAPI.cxx

@@ -7,9 +7,13 @@
 #include <chrono>
 #include <ctime>
 #include <iomanip>
+#include <iterator>
 #include <sstream>
 #include <utility>
 
+#include <cm/optional>
+#include <cmext/string_view>
+
 #include "cmsys/Directory.hxx"
 #include "cmsys/FStream.hxx"
 
@@ -29,7 +33,12 @@ cmFileAPI::cmFileAPI(cmake* cm)
   : CMakeInstance(cm)
 {
   this->APIv1 =
-    this->CMakeInstance->GetHomeOutputDirectory() + "/.cmake/api/v1";
+    cmStrCat(this->CMakeInstance->GetHomeOutputDirectory(), "/.cmake/api/v1");
+
+  if (cm::optional<std::string> cmakeConfigDir =
+        cmSystemTools::GetCMakeConfigDirectory()) {
+    this->UserAPIv1 = cmStrCat(std::move(*cmakeConfigDir), "/api/v1"_s);
+  }
 
   Json::CharReaderBuilder rbuilder;
   rbuilder["collectComments"] = false;
@@ -47,14 +56,24 @@ cmFileAPI::cmFileAPI(cmake* cm)
 
 void cmFileAPI::ReadQueries()
 {
-  std::string const query_dir = this->APIv1 + "/query";
+  std::string const query_dir = cmStrCat(this->APIv1, "/query");
+  std::string const user_query_dir = cmStrCat(this->UserAPIv1, "/query");
   this->QueryExists = cmSystemTools::FileIsDirectory(query_dir);
+  if (!this->UserAPIv1.empty()) {
+    this->QueryExists =
+      this->QueryExists || cmSystemTools::FileIsDirectory(user_query_dir);
+  }
   if (!this->QueryExists) {
     return;
   }
 
   // Load queries at the top level.
   std::vector<std::string> queries = cmFileAPI::LoadDir(query_dir);
+  if (!this->UserAPIv1.empty()) {
+    std::vector<std::string> user_queries = cmFileAPI::LoadDir(user_query_dir);
+    std::move(user_queries.begin(), user_queries.end(),
+              std::back_inserter(queries));
+  }
 
   // Read the queries and save for later.
   for (std::string& query : queries) {

+ 3 - 0
Source/cmFileAPI.h

@@ -61,6 +61,9 @@ private:
   /** The api/v1 directory location.  */
   std::string APIv1;
 
+  /** api/v1 directory in the user's shared CMake config directory.  */
+  std::string UserAPIv1;
+
   /** The set of files we have just written to the reply directory.  */
   std::unordered_set<std::string> ReplyFiles;
 

+ 3 - 1
Source/cmakemain.cxx

@@ -71,7 +71,7 @@ const cmDocumentationEntry cmDocumentationUsageNote = {
   "Run 'cmake --help' for more information."
 };
 
-const cmDocumentationEntry cmDocumentationOptions[33] = {
+const cmDocumentationEntry cmDocumentationOptions[34] = {
   { "--preset <preset>,--preset=<preset>", "Specify a configure preset." },
   { "--list-presets[=<type>]", "List available presets." },
   { "--workflow [<options>]", "Run a workflow preset." },
@@ -94,6 +94,8 @@ const cmDocumentationEntry cmDocumentationOptions[33] = {
     "Generate graphviz of dependencies, see CMakeGraphVizOptions.cmake for "
     "more." },
   { "--system-information [file]", "Dump information about this system." },
+  { "--print-config-dir",
+    "Print CMake config directory for user-wide FileAPI queries." },
   { "--log-level=<ERROR|WARNING|NOTICE|STATUS|VERBOSE|DEBUG|TRACE>",
     "Set the verbosity of messages from CMake files. "
     "--loglevel is also accepted for backward compatibility reasons." },

+ 6 - 3
Tests/CMakeLists.txt

@@ -32,11 +32,14 @@ endmacro()
 include(${CMAKE_CURRENT_SOURCE_DIR}/CheckFortran.cmake)
 include(${CMAKE_CURRENT_SOURCE_DIR}/CheckSwift.cmake)
 
+# Isolate tests from user-wide configuration.
+set(TEST_HOME "${CMake_BINARY_DIR}/Tests/CMakeFiles/TestHome")
+set(TEST_CONFIG_ENV_CODE "# Isolate tests from user-wide configuration.
+set(ENV{CMAKE_CONFIG_DIR} \"${TEST_HOME}/.config/cmake\")\n")
+file(MAKE_DIRECTORY "${TEST_HOME}/.config/cmake")
+
 # Fake a user home directory to avoid polluting the real one.
 if(NOT CTEST_NO_TEST_HOME AND (NOT WIN32 OR DEFINED ENV{HOME}))
-  set(TEST_HOME "${CMake_BINARY_DIR}/Tests/CMakeFiles/TestHome")
-  file(MAKE_DIRECTORY "${TEST_HOME}")
-  file(WRITE "${TEST_HOME}/.cvspass" ":pserver:[email protected]:/cvsroot/KWSys A\n")
   set(TEST_HOME_ENV_CODE "# Fake a user home directory to avoid polluting the real one.
 # But provide original ENV{HOME} value in ENV{CTEST_REAL_HOME} for tests that
 # need access to the real HOME directory.

+ 1 - 0
Tests/EnforceConfig.cmake.in

@@ -38,5 +38,6 @@ unset(ENV{CMAKE_EXPORT_COMPILE_COMMANDS})
 # Verify that our module implementations do not recurse too much.
 set(ENV{CMAKE_MAXIMUM_RECURSION_DEPTH} 100)
 
+@TEST_CONFIG_ENV_CODE@
 @TEST_HOME_ENV_CODE@
 @TEST_WARN_VS_CODE@

+ 1 - 0
Tests/RunCMake/CMakeLists.txt

@@ -409,6 +409,7 @@ if(CMAKE_USE_SYSTEM_JSONCPP)
 endif()
 add_RunCMake_test(FileAPI -DPython_EXECUTABLE=${Python_EXECUTABLE}
                           -DCMAKE_CXX_COMPILER_ID=${CMAKE_CXX_COMPILER_ID})
+add_RunCMake_test(ConfigDir)
 add_RunCMake_test(FindBoost)
 add_RunCMake_test(FindLua)
 add_RunCMake_test(FindOpenGL)

+ 3 - 0
Tests/RunCMake/ConfigDir/CMakeLists.txt

@@ -0,0 +1,3 @@
+cmake_minimum_required(VERSION 3.30)
+project(${RunCMake_TEST} NONE)
+include(${RunCMake_TEST}.cmake)

+ 6 - 0
Tests/RunCMake/ConfigDir/RunCMakeTest.cmake

@@ -0,0 +1,6 @@
+include(RunCMake)
+
+set(ENV{CMAKE_CONFIG_DIR} ${CMAKE_CURRENT_LIST_DIR}/config)
+set(RunCMake-check-file check-reply.cmake)
+run_cmake(config)
+unset(RunCMake-check-file)

+ 3 - 0
Tests/RunCMake/ConfigDir/check-reply.cmake

@@ -0,0 +1,3 @@
+if (NOT EXISTS ${RunCMake_TEST_BINARY_DIR}/.cmake/api/v1/reply)
+  set(RunCMake_TEST_FAILED "Failed to read FileAPI query from user config directory")
+endif()

+ 0 - 0
Tests/RunCMake/ConfigDir/config.cmake


+ 0 - 0
Tests/RunCMake/ConfigDir/config/api/v1/query/codemodel-v2