Add --recursive and --dereference-recursive.

Closes: #5
This commit is contained in:
tastytea 2021-05-27 14:44:56 +02:00
parent b764f5423c
commit 0c45e7ac98
Signed by: tastytea
GPG Key ID: CFC39497F1B26E07
5 changed files with 142 additions and 4 deletions

View File

@ -2,7 +2,7 @@
:doctype: manpage :doctype: manpage
:Author: tastytea :Author: tastytea
:Email: tastytea@tastytea.de :Email: tastytea@tastytea.de
:Date: 2021-05-26 :Date: 2021-05-27
:Revision: 0.0.0 :Revision: 0.0.0
:man source: epubgrep :man source: epubgrep
:man manual: General Commands Manual :man manual: General Commands Manual
@ -61,6 +61,14 @@ Do not color matches.
*--no-filename*:: *--no-filename*::
Suppress the mentioning of file names on output. Chapters and page numbers will Suppress the mentioning of file names on output. Chapters and page numbers will
still be output. still be output.
*-r*, *--recursive*:
Read all files under each directory, recursively, following symbolic links only
if they are on the command line. Silently skips directories that are not
readable by the user.
*-R*, *--dereference-recursive*
Read all files under each directory, recursively. Follow all symbolic
links. Silently skips directories that are not readable by the user.
== USAGE == USAGE

52
src/files.cpp Normal file
View File

@ -0,0 +1,52 @@
/* This file is part of epubgrep.
* Copyright © 2021 tastytea <tastytea@tastytea.de>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, version 3.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "files.hpp"
#include "fs-compat.hpp"
#include <exception>
#include <iostream>
#include <string_view>
#include <vector>
namespace epubgrep::files
{
std::vector<fs::path> list_recursive(const fs::path &directory,
const bool follow_symlinks)
{
fs::directory_options dir_options{
fs::directory_options::skip_permission_denied};
if (follow_symlinks)
{
dir_options |= fs::directory_options::follow_directory_symlink;
}
fs::recursive_directory_iterator dir_iter{directory, dir_options};
std::vector<fs::path> paths;
for (const auto &path : dir_iter)
{
if (!path.is_directory())
{
paths.emplace_back(path);
}
}
return paths;
}
} // namespace epubgrep::files

34
src/files.hpp Normal file
View File

@ -0,0 +1,34 @@
/* This file is part of epubgrep.
* Copyright © 2021 tastytea <tastytea@tastytea.de>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, version 3.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef EPUBGREP_FILES_HPP
#define EPUBGREP_FILES_HPP
#include "fs-compat.hpp"
#include <string_view>
#include <vector>
namespace epubgrep::files
{
//! List files in directory recursively.
[[nodiscard]] std::vector<fs::path> list_recursive(const fs::path &directory,
bool follow_symlinks);
} // namespace epubgrep::files
#endif // EPUBGREP_FILES_HPP

View File

@ -14,6 +14,8 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
#include "files.hpp"
#include "fs-compat.hpp"
#include "options.hpp" #include "options.hpp"
#include "search.hpp" #include "search.hpp"
@ -78,6 +80,8 @@ int main(int argc, char *argv[])
return EXIT_SUCCESS; return EXIT_SUCCESS;
} }
int return_code{EXIT_SUCCESS};
vector<fs::path> input_files; vector<fs::path> input_files;
if (vm.count("input-file") == 0) if (vm.count("input-file") == 0)
{ {
@ -87,10 +91,44 @@ int main(int argc, char *argv[])
} }
for (const auto &filepath : vm["input-file"].as<vector<string>>()) for (const auto &filepath : vm["input-file"].as<vector<string>>())
{ {
input_files.emplace_back(filepath); if (vm.count("recursive") + vm.count("dereference-recursive") == 0)
} {
int return_code{EXIT_SUCCESS}; input_files.emplace_back(filepath);
}
else
{
bool follow_symlinks{false};
if (vm.count("dereference-recursive") > 0)
{
follow_symlinks = true;
}
try
{
auto files_in_dir{
files::list_recursive(filepath, follow_symlinks)};
input_files.insert(input_files.end(), files_in_dir.begin(),
files_in_dir.end());
}
catch (const fs::filesystem_error &e)
{
if (e.code().value() == 20)
{ // Is not a directory.
input_files.emplace_back(filepath);
continue;
}
cerr << '\n'
<< format(translate("ERROR: Could not open {0:s}: {1:s}")
.str()
.data(),
e.path1(), e.what())
<< '\n';
return_code = EXIT_FAILURE;
}
}
}
search::options opts; search::options opts;
if (vm.count("basic-regexp") > 0) if (vm.count("basic-regexp") > 0)

View File

@ -76,6 +76,12 @@ po::variables_map parse_options(int argc, char *argv[])
("no-filename", ("no-filename",
translate("Suppress the mentioning of file names on output.") translate("Suppress the mentioning of file names on output.")
.str().data()) .str().data())
("recursive,r",
translate("Read all files under each directory, recursively.")
.str().data())
("dereference-recursive,R",
translate("Read all files under each directory, recursively, "
"following symlinks.") .str().data())
; ;
po::options_description options_hidden("Hidden options"); po::options_description options_hidden("Hidden options");