mirror of
https://github.com/Kitware/CMake.git
synced 2025-10-14 02:08:27 +08:00
cmake -E: add cat command.
Concatenate files and print on the standard output. FIXES: #20557
This commit is contained in:
@@ -554,6 +554,9 @@ Available commands are:
|
||||
``serverMode``
|
||||
``true`` if cmake supports server-mode and ``false`` otherwise.
|
||||
|
||||
``cat <files>...``
|
||||
Concatenate files and print on the standard output.
|
||||
|
||||
``chdir <dir> <cmd> [<arg>...]``
|
||||
Change the current working directory and run a command.
|
||||
|
||||
|
5
Help/release/dev/command-line-cat.rst
Normal file
5
Help/release/dev/command-line-cat.rst
Normal file
@@ -0,0 +1,5 @@
|
||||
Command-Line
|
||||
------------
|
||||
* :manual:`cmake(1)` gained a ``cat`` command line
|
||||
option that can be used to concatenate files and print them
|
||||
on standard output.
|
@@ -90,6 +90,7 @@ void CMakeCommandUsage(const char* program)
|
||||
<< "Available commands: \n"
|
||||
<< " capabilities - Report capabilities built into cmake "
|
||||
"in JSON format\n"
|
||||
<< " cat <files>... - concat the files and print them to the standard output\n"
|
||||
<< " chdir dir cmd [args...] - run command in a given directory\n"
|
||||
<< " compare_files [--ignore-eol] file1 file2\n"
|
||||
<< " - check if file1 is same as file2\n"
|
||||
@@ -180,6 +181,13 @@ static bool cmTarFilesFrom(std::string const& file,
|
||||
return true;
|
||||
}
|
||||
|
||||
static void cmCatFile(const std::string& fileToAppend)
|
||||
{
|
||||
cmsys::ifstream source(fileToAppend.c_str(),
|
||||
(std::ios::binary | std::ios::in));
|
||||
std::cout << source.rdbuf();
|
||||
}
|
||||
|
||||
static bool cmRemoveDirectory(const std::string& dir, bool recursive = true)
|
||||
{
|
||||
if (cmSystemTools::FileIsSymlink(dir)) {
|
||||
@@ -927,6 +935,33 @@ int cmcmd::ExecuteCMakeCommand(std::vector<std::string> const& args)
|
||||
return HashSumFile(args, cmCryptoHash::AlgoSHA512);
|
||||
}
|
||||
|
||||
// Command to concat files into one
|
||||
if (args[1] == "cat" && args.size() >= 3) {
|
||||
int return_value = 0;
|
||||
for (auto const& arg : cmMakeRange(args).advance(2)) {
|
||||
if (cmHasLiteralPrefix(arg, "-")) {
|
||||
if (arg != "--") {
|
||||
cmSystemTools::Error(arg + ": option not handled");
|
||||
return_value = 1;
|
||||
}
|
||||
} else if (!cmSystemTools::TestFileAccess(arg,
|
||||
cmsys::TEST_FILE_READ) &&
|
||||
cmSystemTools::TestFileAccess(arg, cmsys::TEST_FILE_OK)) {
|
||||
cmSystemTools::Error(arg + ": permission denied (ignoring)");
|
||||
return_value = 1;
|
||||
} else if (cmSystemTools::FileIsDirectory(arg)) {
|
||||
cmSystemTools::Error(arg + ": is a directory (ignoring)");
|
||||
return_value = 1;
|
||||
} else if (!cmSystemTools::FileExists(arg)) {
|
||||
cmSystemTools::Error(arg + ": no such file or directory (ignoring)");
|
||||
return_value = 1;
|
||||
} else {
|
||||
cmCatFile(arg);
|
||||
}
|
||||
}
|
||||
return return_value;
|
||||
}
|
||||
|
||||
// Command to change directory and run a program.
|
||||
if (args[1] == "chdir" && args.size() >= 4) {
|
||||
std::string const& directory = args[2];
|
||||
|
1
Tests/RunCMake/CommandLine/E_cat_directory-result.txt
Normal file
1
Tests/RunCMake/CommandLine/E_cat_directory-result.txt
Normal file
@@ -0,0 +1 @@
|
||||
1
|
1
Tests/RunCMake/CommandLine/E_cat_directory-stderr.txt
Normal file
1
Tests/RunCMake/CommandLine/E_cat_directory-stderr.txt
Normal file
@@ -0,0 +1 @@
|
||||
^CMake Error: .* is a directory
|
3
Tests/RunCMake/CommandLine/E_cat_good_cat-stdout.txt
Normal file
3
Tests/RunCMake/CommandLine/E_cat_good_cat-stdout.txt
Normal file
@@ -0,0 +1,3 @@
|
||||
first file to append
|
||||
second file to append
|
||||
àéùç - 한국어
|
@@ -0,0 +1 @@
|
||||
1
|
@@ -0,0 +1 @@
|
||||
^CMake Error: .*: no such file or directory \(ignoring\)
|
@@ -0,0 +1 @@
|
||||
1
|
@@ -0,0 +1 @@
|
||||
^CMake Error: .*: permission denied \(ignoring\)
|
@@ -0,0 +1 @@
|
||||
1
|
@@ -0,0 +1 @@
|
||||
^CMake Error: -f: option not handled
|
@@ -459,6 +459,44 @@ if(NOT WIN32 AND NOT CYGWIN)
|
||||
endif()
|
||||
unset(out)
|
||||
|
||||
# cat tests
|
||||
set(out ${RunCMake_BINARY_DIR}/cat_tests)
|
||||
file(REMOVE_RECURSE "${out}")
|
||||
file(MAKE_DIRECTORY ${out})
|
||||
run_cmake_command(E_cat_non_existing_file
|
||||
${CMAKE_COMMAND} -E cat ${out}/non-existing-file.txt)
|
||||
|
||||
if(UNIX)
|
||||
# test non readable file only if not root
|
||||
execute_process(
|
||||
COMMAND id -u $ENV{USER}
|
||||
OUTPUT_VARIABLE uid
|
||||
OUTPUT_STRIP_TRAILING_WHITESPACE)
|
||||
|
||||
if(NOT "${uid}" STREQUAL "0")
|
||||
# Create non readable file
|
||||
set(inside_folder "${out}/in")
|
||||
file(MAKE_DIRECTORY ${inside_folder})
|
||||
file(WRITE "${inside_folder}/non_readable_file.txt" "first file to append\n")
|
||||
file(COPY "${inside_folder}/non_readable_file.txt" DESTINATION "${out}" FILE_PERMISSIONS OWNER_WRITE)
|
||||
run_cmake_command(E_cat_non_readable_file
|
||||
${CMAKE_COMMAND} -E cat "${out}/non_readable_file.txt")
|
||||
endif()
|
||||
endif()
|
||||
|
||||
run_cmake_command(E_cat_option_not_handled
|
||||
${CMAKE_COMMAND} -E cat -f)
|
||||
|
||||
run_cmake_command(E_cat_directory
|
||||
${CMAKE_COMMAND} -E cat ${out})
|
||||
|
||||
file(WRITE "${out}/first_file.txt" "first file to append\n")
|
||||
file(WRITE "${out}/second_file.txt" "second file to append\n")
|
||||
file(WRITE "${out}/unicode_file.txt" "àéùç - 한국어") # Korean in Korean
|
||||
run_cmake_command(E_cat_good_cat
|
||||
${CMAKE_COMMAND} -E cat "${out}/first_file.txt" "${out}/second_file.txt" "${out}/unicode_file.txt")
|
||||
unset(out)
|
||||
|
||||
run_cmake_command(E_env-no-command0 ${CMAKE_COMMAND} -E env)
|
||||
run_cmake_command(E_env-no-command1 ${CMAKE_COMMAND} -E env TEST_ENV=1)
|
||||
run_cmake_command(E_env-bad-arg1 ${CMAKE_COMMAND} -E env -bad-arg1)
|
||||
|
Reference in New Issue
Block a user