diff options
author | Brad King <brad.king@kitware.com> | 2020-09-01 13:19:09 (GMT) |
---|---|---|
committer | Kitware Robot <kwrobot@kitware.com> | 2020-09-01 13:19:18 (GMT) |
commit | f7fbe405131eae2e914cd5aec310e1ec2614d840 (patch) | |
tree | 8c243dddcb9e4770e14da5a7e09dc3d6831ebbcd | |
parent | 4a804837502c512610035d4ffb6da3d8d06b79ae (diff) | |
parent | 7de60beddf5b41f643e187fe487ffb91cd47e9f7 (diff) | |
download | CMake-f7fbe405131eae2e914cd5aec310e1ec2614d840.zip CMake-f7fbe405131eae2e914cd5aec310e1ec2614d840.tar.gz CMake-f7fbe405131eae2e914cd5aec310e1ec2614d840.tar.bz2 |
Merge topic 'file_chmod'
7de60beddf file: Add CHMOD and CHMOD_RECURSE subcommands
Acked-by: Kitware Robot <kwrobot@kitware.com>
Acked-by: Marc Chevrier <marc.chevrier@gmail.com>
Merge-request: !5122
26 files changed, 312 insertions, 0 deletions
diff --git a/Help/command/file.rst b/Help/command/file.rst index 953172b..9d6ff91 100644 --- a/Help/command/file.rst +++ b/Help/command/file.rst @@ -30,6 +30,8 @@ Synopsis file(`SIZE`_ <filename> <out-var>) file(`READ_SYMLINK`_ <linkname> <out-var>) file(`CREATE_LINK`_ <original> <linkname> [...]) + file(`CHMOD`_ <files>... <directories>... PERMISSIONS <permissions>... [...]) + file(`CHMOD_RECURSE`_ <files>... <directories>... PERMISSIONS <permissions>... [...]) `Path Conversion`_ file(`RELATIVE_PATH`_ <out-var> <directory> <file>) @@ -741,6 +743,51 @@ creating the link fails. It can be useful for handling situations such as ``<original>`` and ``<linkname>`` being on different drives or mount points, which would make them unable to support a hard link. +.. _CHMOD: + +.. code-block:: cmake + + file(CHMOD <files>... <directories>... [PERMISSIONS <permissions>...] + [FILE_PERMISSIONS <permissions>...] + [DIRECTORY_PERMISSIONS <permissions>...]) + +Set the permissions for the ``<files>...`` and ``<directories>...`` specified. +Valid permissions are ``OWNER_READ``, ``OWNER_WRITE``, ``OWNER_EXECUTE``, +``GROUP_READ``, ``GROUP_WRITE``, ``GROUP_EXECUTE``, ``WORLD_READ``, +``WORLD_WRITE``, ``WORLD_EXECUTE``. + +Valid combination of keywords are: + +``PERMISSIONS`` + all items are changed + +``FILE_PERMISSIONS`` + only files are changed + +``DIRECTORY_PERMISSIONS`` + only directories are changed + +``PERMISSIONS`` and ``FILE_PERMISSIONS`` + ``FILE_PERMISSIONS`` overrides ``PERMISSIONS`` for files + +``PERMISSIONS`` and ``DIRECTORY_PERMISSIONS`` + ``DIRECTORY_PERMISSIONS`` overrides ``PERMISSIONS`` for directories + +``FILE_PERMISSIONS`` and ``DIRECTORY_PERMISSIONS`` + use ``FILE_PERMISSIONS`` for files and ``DIRECTORY_PERMISSIONS`` for + directories + + +.. _CHMOD_RECURSE: + +.. code-block:: cmake + + file(CHMOD_RECURSE <files>... <directories>... PERMISSIONS <permissions>... + FILE_PERMISSIONS <permissions>... DIRECTORY_PERMISSIONS <permissions>...) + +Same as `CHMOD`_, but change the permissions of files and directories present in +the ``<directories>..`` recursively. + Path Conversion ^^^^^^^^^^^^^^^ diff --git a/Help/release/dev/file-CHMOD.rst b/Help/release/dev/file-CHMOD.rst new file mode 100644 index 0000000..994b529 --- /dev/null +++ b/Help/release/dev/file-CHMOD.rst @@ -0,0 +1,5 @@ +file-CHMOD +---------- + +* Add :command:`file(CHMOD)` and :command:`file(CHMOD_RECURSE)` to + set permissions of files and directories. diff --git a/Source/cmFileCommand.cxx b/Source/cmFileCommand.cxx index 550ad6e..f1169cc 100644 --- a/Source/cmFileCommand.cxx +++ b/Source/cmFileCommand.cxx @@ -30,6 +30,7 @@ #include "cmArgumentParser.h" #include "cmCryptoHash.h" #include "cmExecutionStatus.h" +#include "cmFSPermissions.h" #include "cmFileCopier.h" #include "cmFileInstaller.h" #include "cmFileLockPool.h" @@ -3160,6 +3161,163 @@ bool HandleArchiveExtractCommand(std::vector<std::string> const& args, return true; } +bool ValidateAndConvertPermissions(const std::vector<std::string>& permissions, + mode_t& perms, cmExecutionStatus& status) +{ + for (const auto& i : permissions) { + if (!cmFSPermissions::stringToModeT(i, perms)) { + status.SetError(i + " is an invalid permission specifier"); + cmSystemTools::SetFatalErrorOccured(); + return false; + } + } + return true; +} + +bool SetPermissions(const std::string& filename, const mode_t& perms, + cmExecutionStatus& status) +{ + if (!cmSystemTools::SetPermissions(filename, perms)) { + status.SetError("Failed to set permissions for " + filename); + cmSystemTools::SetFatalErrorOccured(); + return false; + } + return true; +} + +bool HandleChmodCommandImpl(std::vector<std::string> const& args, bool recurse, + cmExecutionStatus& status) +{ + mode_t perms = 0; + mode_t fperms = 0; + mode_t dperms = 0; + cmsys::Glob globber; + + globber.SetRecurse(recurse); + globber.SetRecurseListDirs(recurse); + + struct Arguments + { + std::vector<std::string> Permissions; + std::vector<std::string> FilePermissions; + std::vector<std::string> DirectoryPermissions; + }; + + static auto const parser = + cmArgumentParser<Arguments>{} + .Bind("PERMISSIONS"_s, &Arguments::Permissions) + .Bind("FILE_PERMISSIONS"_s, &Arguments::FilePermissions) + .Bind("DIRECTORY_PERMISSIONS"_s, &Arguments::DirectoryPermissions); + + std::vector<std::string> pathEntries; + std::vector<std::string> keywordsMissingValues; + Arguments parsedArgs = parser.Parse(cmMakeRange(args).advance(1), + &pathEntries, &keywordsMissingValues); + + // check validity of arguments + if (parsedArgs.Permissions.empty() && parsedArgs.FilePermissions.empty() && + parsedArgs.DirectoryPermissions.empty()) // no permissions given + { + status.SetError("No permissions given"); + cmSystemTools::SetFatalErrorOccured(); + return false; + } + + if (!parsedArgs.Permissions.empty() && !parsedArgs.FilePermissions.empty() && + !parsedArgs.DirectoryPermissions.empty()) // all keywords are used + { + status.SetError("Remove either PERMISSIONS or FILE_PERMISSIONS or " + "DIRECTORY_PERMISSIONS from the invocation"); + cmSystemTools::SetFatalErrorOccured(); + return false; + } + + if (!keywordsMissingValues.empty()) { + for (const auto& i : keywordsMissingValues) { + status.SetError(i + " is not given any arguments"); + cmSystemTools::SetFatalErrorOccured(); + } + return false; + } + + // validate permissions + bool validatePermissions = + ValidateAndConvertPermissions(parsedArgs.Permissions, perms, status) && + ValidateAndConvertPermissions(parsedArgs.FilePermissions, fperms, + status) && + ValidateAndConvertPermissions(parsedArgs.DirectoryPermissions, dperms, + status); + if (!validatePermissions) { + return false; + } + + std::vector<std::string> allPathEntries; + + if (recurse) { + std::vector<std::string> tempPathEntries; + for (const auto& i : pathEntries) { + if (cmSystemTools::FileIsDirectory(i)) { + globber.FindFiles(i + "/*"); + tempPathEntries = globber.GetFiles(); + allPathEntries.insert(allPathEntries.end(), tempPathEntries.begin(), + tempPathEntries.end()); + allPathEntries.emplace_back(i); + } else { + allPathEntries.emplace_back(i); // We validate path entries below + } + } + } else { + allPathEntries = std::move(pathEntries); + } + + // chmod + for (const auto& i : allPathEntries) { + if (!(cmSystemTools::FileExists(i) || cmSystemTools::FileIsDirectory(i))) { + status.SetError(cmStrCat("does not exist:\n ", i)); + cmSystemTools::SetFatalErrorOccured(); + return false; + } + + if (cmSystemTools::FileExists(i, true)) { + bool success = true; + const mode_t& filePermissions = + parsedArgs.FilePermissions.empty() ? perms : fperms; + if (filePermissions) { + success = SetPermissions(i, filePermissions, status); + } + if (!success) { + return false; + } + } + + else if (cmSystemTools::FileIsDirectory(i)) { + bool success = true; + const mode_t& directoryPermissions = + parsedArgs.DirectoryPermissions.empty() ? perms : dperms; + if (directoryPermissions) { + success = SetPermissions(i, directoryPermissions, status); + } + if (!success) { + return false; + } + } + } + + return true; +} + +bool HandleChmodCommand(std::vector<std::string> const& args, + cmExecutionStatus& status) +{ + return HandleChmodCommandImpl(args, false, status); +} + +bool HandleChmodRecurseCommand(std::vector<std::string> const& args, + cmExecutionStatus& status) +{ + return HandleChmodCommandImpl(args, true, status); +} + } // namespace bool cmFileCommand(std::vector<std::string> const& args, @@ -3216,6 +3374,8 @@ bool cmFileCommand(std::vector<std::string> const& args, { "CONFIGURE"_s, HandleConfigureCommand }, { "ARCHIVE_CREATE"_s, HandleArchiveCreateCommand }, { "ARCHIVE_EXTRACT"_s, HandleArchiveExtractCommand }, + { "CHMOD"_s, HandleChmodCommand }, + { "CHMOD_RECURSE"_s, HandleChmodRecurseCommand }, }; return subcommand(args[0], args, status); diff --git a/Tests/RunCMake/CMakeLists.txt b/Tests/RunCMake/CMakeLists.txt index 65e8b0b..b14b5b5 100644 --- a/Tests/RunCMake/CMakeLists.txt +++ b/Tests/RunCMake/CMakeLists.txt @@ -322,6 +322,7 @@ add_RunCMake_test(ctest_update) add_RunCMake_test(ctest_upload) add_RunCMake_test(ctest_fixtures) add_RunCMake_test(file) +add_RunCMake_test(file-CHMOD) add_RunCMake_test(find_file) add_RunCMake_test(find_library -DCYGWIN=${CYGWIN}) add_RunCMake_test(find_package) diff --git a/Tests/RunCMake/file-CHMOD/CHMOD-all-perms-result.txt b/Tests/RunCMake/file-CHMOD/CHMOD-all-perms-result.txt new file mode 100644 index 0000000..d00491f --- /dev/null +++ b/Tests/RunCMake/file-CHMOD/CHMOD-all-perms-result.txt @@ -0,0 +1 @@ +1 diff --git a/Tests/RunCMake/file-CHMOD/CHMOD-all-perms-stderr.txt b/Tests/RunCMake/file-CHMOD/CHMOD-all-perms-stderr.txt new file mode 100644 index 0000000..b22387b --- /dev/null +++ b/Tests/RunCMake/file-CHMOD/CHMOD-all-perms-stderr.txt @@ -0,0 +1,5 @@ +CMake Error at CHMOD-all-perms\.cmake:[0-9]+ \(file\): + file Remove either PERMISSIONS or FILE_PERMISSIONS or DIRECTORY_PERMISSIONS + from the invocation +Call Stack \(most recent call first\): + CMakeLists\.txt:[0-9]+ \(include\) diff --git a/Tests/RunCMake/file-CHMOD/CHMOD-all-perms.cmake b/Tests/RunCMake/file-CHMOD/CHMOD-all-perms.cmake new file mode 100644 index 0000000..b49583d --- /dev/null +++ b/Tests/RunCMake/file-CHMOD/CHMOD-all-perms.cmake @@ -0,0 +1,6 @@ +file(REMOVE_RECURSE ${CMAKE_CURRENT_BINARY_DIR}/chmod-tests) +file(MAKE_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/chmod-tests) + +file(TOUCH ${CMAKE_CURRENT_BINARY_DIR}/chmod-tests/a) +file(CHMOD ${CMAKE_CURRENT_BINARY_DIR}/chmod-tests/a PERMISSIONS OWNER_READ + FILE_PERMISSIONS OWNER_READ DIRECTORY_PERMISSIONS OWNER_READ) diff --git a/Tests/RunCMake/file-CHMOD/CHMOD-invalid-path-result.txt b/Tests/RunCMake/file-CHMOD/CHMOD-invalid-path-result.txt new file mode 100644 index 0000000..d00491f --- /dev/null +++ b/Tests/RunCMake/file-CHMOD/CHMOD-invalid-path-result.txt @@ -0,0 +1 @@ +1 diff --git a/Tests/RunCMake/file-CHMOD/CHMOD-invalid-path-stderr.txt b/Tests/RunCMake/file-CHMOD/CHMOD-invalid-path-stderr.txt new file mode 100644 index 0000000..8d09e35 --- /dev/null +++ b/Tests/RunCMake/file-CHMOD/CHMOD-invalid-path-stderr.txt @@ -0,0 +1,6 @@ +CMake Error at CHMOD-invalid-path\.cmake:[0-9]+ \(file\): + file does not exist: + + .*/chmod-tests/I_dont_exist +Call Stack \(most recent call first\): + CMakeLists\.txt:[0-9]+ \(include\) diff --git a/Tests/RunCMake/file-CHMOD/CHMOD-invalid-path.cmake b/Tests/RunCMake/file-CHMOD/CHMOD-invalid-path.cmake new file mode 100644 index 0000000..36915c1 --- /dev/null +++ b/Tests/RunCMake/file-CHMOD/CHMOD-invalid-path.cmake @@ -0,0 +1,4 @@ +file(REMOVE_RECURSE ${CMAKE_CURRENT_BINARY_DIR}/chmod-tests) +file(MAKE_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/chmod-tests) + +file(CHMOD ${CMAKE_CURRENT_BINARY_DIR}/chmod-tests/I_dont_exist PERMISSIONS OWNER_READ) diff --git a/Tests/RunCMake/file-CHMOD/CHMOD-invalid-perms-result.txt b/Tests/RunCMake/file-CHMOD/CHMOD-invalid-perms-result.txt new file mode 100644 index 0000000..d00491f --- /dev/null +++ b/Tests/RunCMake/file-CHMOD/CHMOD-invalid-perms-result.txt @@ -0,0 +1 @@ +1 diff --git a/Tests/RunCMake/file-CHMOD/CHMOD-invalid-perms-stderr.txt b/Tests/RunCMake/file-CHMOD/CHMOD-invalid-perms-stderr.txt new file mode 100644 index 0000000..84ba2a2 --- /dev/null +++ b/Tests/RunCMake/file-CHMOD/CHMOD-invalid-perms-stderr.txt @@ -0,0 +1,4 @@ +CMake Error at CHMOD-invalid-perms\.cmake:[0-9]+ \(file\): + file INVALID_PERMISSION is an invalid permission specifier +Call Stack \(most recent call first\): + CMakeLists\.txt:[0-9]+ \(include\) diff --git a/Tests/RunCMake/file-CHMOD/CHMOD-invalid-perms.cmake b/Tests/RunCMake/file-CHMOD/CHMOD-invalid-perms.cmake new file mode 100644 index 0000000..22cab0b --- /dev/null +++ b/Tests/RunCMake/file-CHMOD/CHMOD-invalid-perms.cmake @@ -0,0 +1,5 @@ +file(REMOVE_RECURSE ${CMAKE_CURRENT_BINARY_DIR}/chmod-tests) +file(MAKE_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/chmod-tests) + +file(TOUCH ${CMAKE_CURRENT_BINARY_DIR}/chmod-tests/a) +file(CHMOD ${CMAKE_CURRENT_BINARY_DIR}/chmod-tests/a PERMISSIONS INVALID_PERMISSION) diff --git a/Tests/RunCMake/file-CHMOD/CHMOD-no-keyword-result.txt b/Tests/RunCMake/file-CHMOD/CHMOD-no-keyword-result.txt new file mode 100644 index 0000000..d00491f --- /dev/null +++ b/Tests/RunCMake/file-CHMOD/CHMOD-no-keyword-result.txt @@ -0,0 +1 @@ +1 diff --git a/Tests/RunCMake/file-CHMOD/CHMOD-no-keyword-stderr.txt b/Tests/RunCMake/file-CHMOD/CHMOD-no-keyword-stderr.txt new file mode 100644 index 0000000..2c248f8 --- /dev/null +++ b/Tests/RunCMake/file-CHMOD/CHMOD-no-keyword-stderr.txt @@ -0,0 +1,4 @@ +CMake Error at CHMOD-no-keyword\.cmake:[0-9]+ \(file\): + file No permissions given +Call Stack \(most recent call first\): + CMakeLists\.txt:[0-9]+ \(include\) diff --git a/Tests/RunCMake/file-CHMOD/CHMOD-no-keyword.cmake b/Tests/RunCMake/file-CHMOD/CHMOD-no-keyword.cmake new file mode 100644 index 0000000..8b62106 --- /dev/null +++ b/Tests/RunCMake/file-CHMOD/CHMOD-no-keyword.cmake @@ -0,0 +1,5 @@ +file(REMOVE_RECURSE ${CMAKE_CURRENT_BINARY_DIR}/chmod-tests) +file(MAKE_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/chmod-tests) + +file(TOUCH ${CMAKE_CURRENT_BINARY_DIR}/chmod-tests/a) +file(CHMOD ${CMAKE_CURRENT_BINARY_DIR}/chmod-tests/a) diff --git a/Tests/RunCMake/file-CHMOD/CHMOD-no-perms-result.txt b/Tests/RunCMake/file-CHMOD/CHMOD-no-perms-result.txt new file mode 100644 index 0000000..d00491f --- /dev/null +++ b/Tests/RunCMake/file-CHMOD/CHMOD-no-perms-result.txt @@ -0,0 +1 @@ +1 diff --git a/Tests/RunCMake/file-CHMOD/CHMOD-no-perms-stderr.txt b/Tests/RunCMake/file-CHMOD/CHMOD-no-perms-stderr.txt new file mode 100644 index 0000000..a18609f --- /dev/null +++ b/Tests/RunCMake/file-CHMOD/CHMOD-no-perms-stderr.txt @@ -0,0 +1,4 @@ +CMake Error at CHMOD-no-perms\.cmake:[0-9]+ \(file\): + file No permissions given +Call Stack \(most recent call first\): + CMakeLists\.txt:[0-9]+ \(include\) diff --git a/Tests/RunCMake/file-CHMOD/CHMOD-no-perms.cmake b/Tests/RunCMake/file-CHMOD/CHMOD-no-perms.cmake new file mode 100644 index 0000000..9fbd359 --- /dev/null +++ b/Tests/RunCMake/file-CHMOD/CHMOD-no-perms.cmake @@ -0,0 +1,5 @@ +file(REMOVE_RECURSE ${CMAKE_CURRENT_BINARY_DIR}/chmod-tests) +file(MAKE_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/chmod-tests) + +file(TOUCH ${CMAKE_CURRENT_BINARY_DIR}/chmod-tests/a) +file(CHMOD ${CMAKE_CURRENT_BINARY_DIR}/chmod-tests/a PERMISSIONS) diff --git a/Tests/RunCMake/file-CHMOD/CHMOD-ok.cmake b/Tests/RunCMake/file-CHMOD/CHMOD-ok.cmake new file mode 100644 index 0000000..87e3e57 --- /dev/null +++ b/Tests/RunCMake/file-CHMOD/CHMOD-ok.cmake @@ -0,0 +1,5 @@ +file(REMOVE_RECURSE ${CMAKE_CURRENT_BINARY_DIR}/chmod-tests) +file(MAKE_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/chmod-tests) + +file(TOUCH ${CMAKE_CURRENT_BINARY_DIR}/chmod-tests/a) +file(CHMOD ${CMAKE_CURRENT_BINARY_DIR}/chmod-tests/a PERMISSIONS OWNER_READ) diff --git a/Tests/RunCMake/file-CHMOD/CHMOD-override.cmake b/Tests/RunCMake/file-CHMOD/CHMOD-override.cmake new file mode 100644 index 0000000..d9226b8 --- /dev/null +++ b/Tests/RunCMake/file-CHMOD/CHMOD-override.cmake @@ -0,0 +1,6 @@ +file(REMOVE_RECURSE ${CMAKE_CURRENT_BINARY_DIR}/chmod-tests) +file(MAKE_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/chmod-tests) + +file(TOUCH ${CMAKE_CURRENT_BINARY_DIR}/chmod-tests/a) +file(CHMOD ${CMAKE_CURRENT_BINARY_DIR}/chmod-tests/a PERMISSIONS OWNER_READ + FILE_PERMISSIONS OWNER_READ OWNER_WRITE) diff --git a/Tests/RunCMake/file-CHMOD/CHMOD-write-only-result.txt b/Tests/RunCMake/file-CHMOD/CHMOD-write-only-result.txt new file mode 100644 index 0000000..d00491f --- /dev/null +++ b/Tests/RunCMake/file-CHMOD/CHMOD-write-only-result.txt @@ -0,0 +1 @@ +1 diff --git a/Tests/RunCMake/file-CHMOD/CHMOD-write-only-stderr.txt b/Tests/RunCMake/file-CHMOD/CHMOD-write-only-stderr.txt new file mode 100644 index 0000000..1c87a59 --- /dev/null +++ b/Tests/RunCMake/file-CHMOD/CHMOD-write-only-stderr.txt @@ -0,0 +1,6 @@ +CMake Error at CHMOD-write-only\.cmake:[0-9]+ \(file\): + file failed to open for reading \(Permission denied\): + + .*/chmod-tests/a +Call Stack \(most recent call first\): + CMakeLists\.txt:[0-9]+ \(include\) diff --git a/Tests/RunCMake/file-CHMOD/CHMOD-write-only.cmake b/Tests/RunCMake/file-CHMOD/CHMOD-write-only.cmake new file mode 100644 index 0000000..1289efc --- /dev/null +++ b/Tests/RunCMake/file-CHMOD/CHMOD-write-only.cmake @@ -0,0 +1,6 @@ +file(REMOVE_RECURSE ${CMAKE_CURRENT_BINARY_DIR}/chmod-tests) +file(MAKE_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/chmod-tests) + +file(WRITE ${CMAKE_CURRENT_BINARY_DIR}/chmod-tests/a "CONTENT") +file(CHMOD ${CMAKE_CURRENT_BINARY_DIR}/chmod-tests/a PERMISSIONS OWNER_WRITE) +file(READ ${CMAKE_CURRENT_BINARY_DIR}/chmod-tests/a content) diff --git a/Tests/RunCMake/file-CHMOD/CMakeLists.txt b/Tests/RunCMake/file-CHMOD/CMakeLists.txt new file mode 100644 index 0000000..2897109 --- /dev/null +++ b/Tests/RunCMake/file-CHMOD/CMakeLists.txt @@ -0,0 +1,3 @@ +cmake_minimum_required(VERSION 3.0) +project(${RunCMake_TEST} NONE) +include(${RunCMake_TEST}.cmake) diff --git a/Tests/RunCMake/file-CHMOD/RunCMakeTest.cmake b/Tests/RunCMake/file-CHMOD/RunCMakeTest.cmake new file mode 100644 index 0000000..c7bff15 --- /dev/null +++ b/Tests/RunCMake/file-CHMOD/RunCMakeTest.cmake @@ -0,0 +1,19 @@ +include(RunCMake) + +run_cmake(CHMOD-no-perms) +run_cmake(CHMOD-no-keyword) +run_cmake(CHMOD-all-perms) +run_cmake(CHMOD-invalid-perms) +run_cmake(CHMOD-invalid-path) +run_cmake(CHMOD-ok) +run_cmake(CHMOD-override) + +if(UNIX) + execute_process(COMMAND id -u $ENV{USER} + OUTPUT_VARIABLE uid + OUTPUT_STRIP_TRAILING_WHITESPACE) +endif() + +if(NOT WIN32 AND NOT "${uid}" STREQUAL "0") + run_cmake(CHMOD-write-only) +endif() |