sapling/eden/fs/store/PathLoader.cpp
Chad Austin 68cf44a8d1 add eden glob command
Summary:
It's silly to use `eden prefetch --no-prefetch` to efficiently glob
for filenames. Introduce an `eden glob` command which resolves a glob
relative to the current working directory.

Reviewed By: genevievehelsel

Differential Revision: D25450358

fbshipit-source-id: 45d6dc870d21510e51d5662c75e80385886899fc
2021-02-23 19:58:03 -08:00

77 lines
2.1 KiB
C++

/*
* Copyright (c) Facebook, Inc. and its affiliates.
*
* This software may be used and distributed according to the terms of the
* GNU General Public License version 2.
*/
#include "eden/fs/store/PathLoader.h"
#include <vector>
#include "eden/fs/model/Tree.h"
#include "eden/fs/service/gen-cpp2/eden_constants.h"
#include "eden/fs/store/ObjectStore.h"
#include "eden/fs/utils/EdenError.h"
namespace facebook::eden {
namespace {
struct ResolveTreeContext {
std::vector<PathComponent> components;
};
folly::Future<std::shared_ptr<const Tree>> resolveTree(
std::shared_ptr<ResolveTreeContext> ctx,
ObjectStore& objectStore,
ObjectFetchContext& fetchContext,
std::shared_ptr<const Tree> root,
size_t index) {
if (index == ctx->components.size()) {
return std::move(root);
}
auto* child = root->getEntryPtr(ctx->components[index]);
if (!child) {
throw newEdenError(
ENOENT,
EdenErrorType::POSIX_ERROR,
"no child with name ",
ctx->components[index]);
}
if (!child->isTree()) {
throw newEdenError(
ENOTDIR,
EdenErrorType::POSIX_ERROR,
"child is not tree ",
ctx->components[index]);
}
return objectStore.getTree(child->getHash(), fetchContext)
.thenValue([ctx = std::move(ctx), &objectStore, &fetchContext, index](
std::shared_ptr<const Tree>&& tree) mutable {
return resolveTree(
ctx, objectStore, fetchContext, std::move(tree), index + 1);
});
}
} // namespace
folly::Future<std::shared_ptr<const Tree>> resolveTree(
ObjectStore& objectStore,
ObjectFetchContext& fetchContext,
std::shared_ptr<const Tree> root,
RelativePathPiece path) {
// Don't do anything fancy with lifetimes and just get this correct as simply
// as possible. There's room for optimization if it matters.
auto ctx = std::make_shared<ResolveTreeContext>();
for (auto c : path.components()) {
ctx->components.emplace_back(c);
}
return resolveTree(
std::move(ctx), objectStore, fetchContext, std::move(root), 0);
}
} // namespace facebook::eden