Contains patch from Rafael to fix up includes. * seastar c872c3408c...7f7cf0f232 (9): > future: Consider result_unavailable invalid in future_state_base::ignore() > future: Consider result_unavailable invalid in future_state_base::valid() > Merge "future-util: split header" from Benny > docs: corrected some text and code-examples in streaming-rpc docs > future: Reduce nesting in future::then > demos: coroutines: include std-compat.hh > sstring: mark str() and methods using it as noexcept > tls: Add an assert > future: fix coroutine compilation
176 lines
7.5 KiB
C++
176 lines
7.5 KiB
C++
/*
|
|
* Copyright (C) 2017 ScyllaDB
|
|
*/
|
|
|
|
/*
|
|
* This file is part of Scylla.
|
|
*
|
|
* Scylla 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, either version 3 of the License, or
|
|
* (at your option) any later version.
|
|
*
|
|
* Scylla 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 General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU General Public License
|
|
* along with Scylla. If not, see <http://www.gnu.org/licenses/>.
|
|
*/
|
|
|
|
#pragma once
|
|
|
|
#include <unordered_set>
|
|
#include <filesystem>
|
|
#include <seastar/core/shared_ptr.hh>
|
|
#include <seastar/core/file.hh>
|
|
#include <seastar/core/enum.hh>
|
|
#include <seastar/util/bool_class.hh>
|
|
|
|
#include "seastarx.hh"
|
|
|
|
namespace fs = std::filesystem;
|
|
|
|
class lister final {
|
|
public:
|
|
/**
|
|
* Types of entries to list. If empty - list all present entries except for
|
|
* hidden if not requested to.
|
|
*/
|
|
using dir_entry_types = std::unordered_set<directory_entry_type, enum_hash<directory_entry_type>>;
|
|
/**
|
|
* This callback is going to be called for each entry in the given directory
|
|
* that has the corresponding type and meets the filter demands.
|
|
*
|
|
* First parameter is a path object for the base directory.
|
|
*
|
|
* Second parameter is a directory_entry object of the file for which this
|
|
* callback is being called.
|
|
*
|
|
* The first parameter of the callback represents a parent directory of
|
|
* each entry defined by the second parameter.
|
|
*/
|
|
using walker_type = std::function<future<> (fs::path, directory_entry)>;
|
|
using filter_type = std::function<bool (const fs::path&, const directory_entry&)>;
|
|
|
|
struct show_hidden_tag {};
|
|
using show_hidden = bool_class<show_hidden_tag>;
|
|
|
|
private:
|
|
file _f;
|
|
walker_type _walker;
|
|
filter_type _filter;
|
|
dir_entry_types _expected_type;
|
|
future<> _listing_done;
|
|
fs::path _dir;
|
|
show_hidden _show_hidden;
|
|
|
|
public:
|
|
/**
|
|
* Scans the directory calling a "walker" callback for each entry that satisfies the filtering.
|
|
*
|
|
* @param dir Directory to scan.
|
|
* @param type Type of entries to process. Entries of other types will be ignored.
|
|
* @param do_show_hidden if TRUE - the hidden entries are going to be processed as well.
|
|
* @param walker A callback to be called for each entry that satisfies the filtering rules.
|
|
* @param filter A filter callback that is called for each entry of the requested type: if returns FALSE - the entry will be skipped.
|
|
*
|
|
* @return A future that resolves when all entries processing is finished or an error occurs. In the later case an exceptional future is returened.
|
|
*/
|
|
static future<> scan_dir(fs::path dir, dir_entry_types type, show_hidden do_show_hidden, walker_type walker, filter_type filter);
|
|
|
|
/**
|
|
* Overload of scan_dir() that uses a show_hidden::no when it's not given.
|
|
*/
|
|
static future<> scan_dir(fs::path dir, dir_entry_types type, walker_type walker, filter_type filter) {
|
|
return scan_dir(std::move(dir), std::move(type), show_hidden::no, std::move(walker), std::move(filter));
|
|
}
|
|
|
|
/**
|
|
* Overload of scan_dir() that uses a show_hidden::no and a filter that returns TRUE for every entry when they are not given.
|
|
*/
|
|
static future<> scan_dir(fs::path dir, dir_entry_types type, walker_type walker) {
|
|
return scan_dir(std::move(dir), std::move(type), show_hidden::no, std::move(walker), [] (const fs::path& parent_dir, const directory_entry& entry) { return true; });
|
|
}
|
|
|
|
/**
|
|
* Overload of scan_dir() that uses a filter that returns TRUE for every entry when filter is not given.
|
|
*/
|
|
static future<> scan_dir(fs::path dir, dir_entry_types type, show_hidden do_show_hidden, walker_type walker) {
|
|
return scan_dir(std::move(dir), std::move(type), do_show_hidden, std::move(walker), [] (const fs::path& parent_dir, const directory_entry& entry) { return true; });
|
|
}
|
|
|
|
/** Overloads accepting sstring as the first parameter */
|
|
static future<> scan_dir(sstring dir, dir_entry_types type, show_hidden do_show_hidden, walker_type walker, filter_type filter) {
|
|
return scan_dir(fs::path(std::move(dir)), std::move(type), do_show_hidden, std::move(walker), std::move(filter));
|
|
}
|
|
static future<> scan_dir(sstring dir, dir_entry_types type, walker_type walker, filter_type filter) {
|
|
return scan_dir(fs::path(std::move(dir)), std::move(type), show_hidden::no, std::move(walker), std::move(filter));
|
|
}
|
|
static future<> scan_dir(sstring dir, dir_entry_types type, walker_type walker) {
|
|
return scan_dir(fs::path(std::move(dir)), std::move(type), show_hidden::no, std::move(walker), [] (const fs::path& parent_dir, const directory_entry& entry) { return true; });
|
|
}
|
|
static future<> scan_dir(sstring dir, dir_entry_types type, show_hidden do_show_hidden, walker_type walker) {
|
|
return scan_dir(fs::path(std::move(dir)), std::move(type), do_show_hidden, std::move(walker), [] (const fs::path& parent_dir, const directory_entry& entry) { return true; });
|
|
}
|
|
|
|
/**
|
|
* Removes the given directory with all its contents (like 'rm -rf <dir>' shell command).
|
|
*
|
|
* @param dir Directory to remove.
|
|
* @return A future that resolves when the operation is complete or an error occurs.
|
|
*/
|
|
static future<> rmdir(fs::path dir);
|
|
|
|
/**
|
|
* Constructor
|
|
*
|
|
* @param f A file instance for the directory to scan.
|
|
* @param type Types of entries to scan.
|
|
* @param walker A callback to be called for each entry that satisfies the filtering rules.
|
|
* @param filter A filter callback that is called for each entry of the requested type: if returns FALSE - the entry will be skipped.
|
|
* @param dir A seastar::path object for the directory to scan.
|
|
* @param do_show_hidden if TRUE - scan hidden entries as well.
|
|
*/
|
|
lister(file f, dir_entry_types type, walker_type walker, filter_type filter, fs::path dir, show_hidden do_show_hidden);
|
|
|
|
/**
|
|
* @return a future that resolves when the directory scanning is complete.
|
|
*/
|
|
future<> done();
|
|
|
|
private:
|
|
/**
|
|
* Handle a single entry.
|
|
*
|
|
* @param de Descriptor of the entry to handle.
|
|
* @return A future that resolves when the handling is over.
|
|
*/
|
|
future<> visit(directory_entry de);
|
|
|
|
/**
|
|
* Validates that the input parameter has its "type" optional field engaged.
|
|
*
|
|
* This helper method is called before further processing the @param de in order
|
|
* to ensure that its "type" field is engaged.
|
|
*
|
|
* If it is engaged - returns the input value as is.
|
|
* If "type" isn't engaged - calls the file_type() for file represented by @param de and sets
|
|
* "type" field of @param de to the returned value and then returns @param de.
|
|
*
|
|
* @param de entry to check and return
|
|
* @return a future that resolves with the @param de with the engaged de.type field or an
|
|
* exceptional future with std::system_error exception if type of the file represented by @param de may not be retrieved.
|
|
*/
|
|
future<directory_entry> guarantee_type(directory_entry de);
|
|
};
|
|
|
|
static inline fs::path operator/(const fs::path& lhs, const char* rhs) {
|
|
return lhs / fs::path(rhs);
|
|
}
|
|
|
|
static inline fs::path operator/(const fs::path& lhs, const sstring& rhs) {
|
|
return lhs / fs::path(rhs);
|
|
}
|