Skip to content

Commit de3f24c

Browse files
authored
Merge pull request #12019 from swiftlang/eng/blangmuir/filesystem-print-impl-cas
[cas] FileSystem::printImpl for CAS-related filesystems
2 parents 0c6db78 + 4d62632 commit de3f24c

File tree

5 files changed

+159
-13
lines changed

5 files changed

+159
-13
lines changed

clang/lib/CAS/IncludeTree.cpp

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1039,6 +1039,26 @@ class IncludeTreeFileSystem final : public llvm::cas::CASBackedFileSystem {
10391039
createThreadSafeProxyFS() override {
10401040
llvm::report_fatal_error("not implemented");
10411041
}
1042+
1043+
void printImpl(raw_ostream &OS, PrintType Type,
1044+
unsigned IndentLevel) const final {
1045+
printIndent(OS, IndentLevel);
1046+
IndentLevel += 1;
1047+
OS << "IncludeTreeFileSystem\n";
1048+
if (Type == PrintType::Summary)
1049+
return;
1050+
1051+
// Files is unordered, so sort by name to get a deterministic order.
1052+
std::vector<std::pair<StringRef, ObjectRef>> FileRefs;
1053+
for (auto &[Name, F] : Files)
1054+
FileRefs.emplace_back(Name, F.ContentsRef);
1055+
llvm::sort(FileRefs, [](auto &&A, auto &&B) { return A.first < B.first; });
1056+
1057+
for (auto &[Name, ContentsRef] : FileRefs) {
1058+
printIndent(OS, IndentLevel);
1059+
OS << Name << ' ' << CAS.getID(ContentsRef) << '\n';
1060+
}
1061+
}
10421062
};
10431063
} // namespace
10441064

clang/unittests/CAS/IncludeTreeTest.cpp

Lines changed: 44 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -300,27 +300,29 @@ TEST(IncludeTree, IncludeTreeFileListDuplicates) {
300300
EXPECT_EQ(I, Files.size());
301301
}
302302

303-
TEST(IncludeTree, IncludeTreeFileSystemOverlay) {
304-
StringRef PathSep = llvm::sys::path::get_separator();
305-
std::shared_ptr<ObjectStore> DB = llvm::cas::createInMemoryCAS();
303+
static Expected<IntrusiveRefCntPtr<llvm::vfs::FileSystem>>
304+
createTestInclueTreeFS(ObjectStore &DB, unsigned NumFiles = 10) {
306305
SmallVector<IncludeTree::FileList::FileEntry> Files;
307-
for (unsigned I = 0; I < 10; ++I) {
306+
for (unsigned I = 0; I < NumFiles; ++I) {
308307
std::optional<IncludeTree::File> File;
309308
std::string Path = "/file" + std::to_string(I);
310309
static constexpr StringRef Bytes = "123456789";
311310
std::optional<ObjectRef> Content;
312-
ASSERT_THAT_ERROR(
313-
DB->storeFromString({}, Bytes.substr(0, I)).moveInto(Content),
314-
llvm::Succeeded());
315-
ASSERT_THAT_ERROR(
316-
IncludeTree::File::create(*DB, Path, *Content).moveInto(File),
317-
llvm::Succeeded());
311+
if (auto E = DB.storeFromString({}, Bytes.substr(0, I)).moveInto(Content))
312+
return std::move(E);
313+
if (auto E = IncludeTree::File::create(DB, Path, *Content).moveInto(File))
314+
return std::move(E);
318315
Files.push_back({File->getRef(), I});
319316
}
317+
return createIncludeTreeFileSystem(DB, Files);
318+
}
319+
320+
TEST(IncludeTree, IncludeTreeFileSystemOverlay) {
321+
StringRef PathSep = llvm::sys::path::get_separator();
322+
std::shared_ptr<ObjectStore> DB = llvm::cas::createInMemoryCAS();
320323
IntrusiveRefCntPtr<llvm::vfs::FileSystem> IncludeTreeFS;
321-
ASSERT_THAT_ERROR(
322-
createIncludeTreeFileSystem(*DB, Files).moveInto(IncludeTreeFS),
323-
llvm::Succeeded());
324+
ASSERT_THAT_ERROR(createTestInclueTreeFS(*DB).moveInto(IncludeTreeFS),
325+
llvm::Succeeded());
324326

325327
auto FS = llvm::makeIntrusiveRefCnt<llvm::vfs::InMemoryFileSystem>();
326328
FS->setCurrentWorkingDirectory("/dir");
@@ -342,3 +344,32 @@ TEST(IncludeTree, IncludeTreeFileSystemOverlay) {
342344
}
343345
ASSERT_EQ(NumFile, 2);
344346
}
347+
348+
TEST(IncludeTree, IncludeTreeFileSystemPrint) {
349+
std::shared_ptr<ObjectStore> DB = llvm::cas::createInMemoryCAS();
350+
IntrusiveRefCntPtr<llvm::vfs::FileSystem> IncludeTreeFS;
351+
ASSERT_THAT_ERROR(
352+
createTestInclueTreeFS(*DB, /*NumFiles=*/3).moveInto(IncludeTreeFS),
353+
llvm::Succeeded());
354+
355+
{
356+
std::string FSStr;
357+
llvm::raw_string_ostream OS(FSStr);
358+
IncludeTreeFS->print(OS, llvm::vfs::FileSystem::PrintType::Summary);
359+
EXPECT_EQ(FSStr, "IncludeTreeFileSystem\n");
360+
}
361+
{
362+
std::string FSStr;
363+
llvm::raw_string_ostream OS(FSStr);
364+
IncludeTreeFS->print(OS, llvm::vfs::FileSystem::PrintType::Contents);
365+
StringRef Printed(FSStr);
366+
EXPECT_TRUE(Printed.consume_front("IncludeTreeFileSystem")) << Printed;
367+
EXPECT_TRUE(Printed.consume_front("\n /file0 llvmcas://")) << Printed;
368+
Printed = Printed.drop_front(64); // 32 hash bytes in hex
369+
EXPECT_TRUE(Printed.consume_front("\n /file1 llvmcas://")) << Printed;
370+
Printed = Printed.drop_front(64); // 32 hash bytes in hex
371+
EXPECT_TRUE(Printed.consume_front("\n /file2 llvmcas://")) << Printed;
372+
Printed = Printed.drop_front(64); // 32 hash bytes in hex
373+
EXPECT_EQ(Printed, "\n"); // Final newline.
374+
}
375+
}

llvm/lib/CAS/CASFileSystem.cpp

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -96,6 +96,9 @@ class CASFileSystem final
9696
return WorkingDirectory.Path;
9797
}
9898

99+
void printImpl(raw_ostream &OS, PrintType Type,
100+
unsigned IndentLevel) const final;
101+
99102
Error initialize(ObjectRef Root);
100103

101104
CASFileSystem(std::shared_ptr<ObjectStore> DB, sys::path::Style PathStyle)
@@ -184,6 +187,45 @@ std::error_code CASFileSystem::setCurrentWorkingDirectory(const Twine &Path) {
184187
return std::error_code();
185188
}
186189

190+
void CASFileSystem::printImpl(raw_ostream &OS, PrintType Type,
191+
unsigned IndentLevel) const {
192+
printIndent(OS, IndentLevel);
193+
OS << "CASFileSystem\n";
194+
if (Type == PrintType::Summary)
195+
return;
196+
197+
IndentLevel += 1;
198+
printIndent(OS, IndentLevel);
199+
StringRef path_separator = get_separator(PathStyle);
200+
auto &Root = Cache->getRoot(path_separator);
201+
OS << "root: " << Root.getTreePath();
202+
assert(Root.getRef() && "missing ID for primary CASFileSystem root");
203+
if (Root.getRef())
204+
OS << ' ' << DB.getID(*Root.getRef()) << '\n';
205+
206+
if (Type == PrintType::Contents)
207+
return;
208+
209+
IndentLevel += 1;
210+
TreeSchema Schema(DB);
211+
auto TreeN = DB.getProxy(*Root.getRef());
212+
if (!TreeN) {
213+
OS << toString(TreeN.takeError()) << '\n';
214+
return;
215+
}
216+
Error E = Schema.walkFileTreeRecursively(
217+
DB, TreeN->getRef(),
218+
[&](const NamedTreeEntry &Entry, std::optional<TreeProxy> Tree) -> Error {
219+
if (Entry.getKind() != TreeEntry::Tree) {
220+
printIndent(OS, IndentLevel);
221+
Entry.print(OS, DB);
222+
}
223+
return Error::success();
224+
});
225+
if (E)
226+
OS << toString(std::move(E)) << '\n';
227+
}
228+
187229
Error CASFileSystem::loadDirectory(DirectoryEntry &Parent) {
188230
Directory &D = Parent.asDirectory();
189231
if (D.isComplete())

llvm/lib/CAS/CachingOnDiskFileSystem.cpp

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -123,6 +123,9 @@ class CachingOnDiskFileSystemImpl final : public CachingOnDiskFileSystem {
123123
return makeIntrusiveRefCnt<CachingOnDiskFileSystemImpl>(*this);
124124
}
125125

126+
void printImpl(raw_ostream &OS, PrintType Type,
127+
unsigned IndentLevel) const final;
128+
126129
CachingOnDiskFileSystemImpl(std::shared_ptr<ObjectStore> DB)
127130
: CachingOnDiskFileSystem(std::move(DB)) {
128131
initializeWorkingDirectory();
@@ -899,6 +902,13 @@ CachingOnDiskFileSystemImpl::createTreeBuilder() {
899902
return std::make_unique<TreeBuilder>(*this);
900903
}
901904

905+
void CachingOnDiskFileSystemImpl::printImpl(raw_ostream &OS, PrintType Type,
906+
unsigned IndentLevel) const {
907+
printIndent(OS, IndentLevel);
908+
OS << "CachingOnDiskFileSystem\n";
909+
// FIXME: print contents
910+
}
911+
902912
void CachingOnDiskFileSystemImpl::TreeBuilder::pushSymlink(
903913
const DirectoryEntry &Entry) {
904914
assert(Entry.isSymlink());

llvm/unittests/CAS/CASFileSystemTest.cpp

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -516,3 +516,46 @@ TEST(CASFileSystemTest, recursiveDirectoryIteratorNested) {
516516
sys::fs::file_type::regular_file));
517517
ASSERT_TRUE(isEnd(D, EC));
518518
}
519+
520+
TEST(CASFileSystemTest, print) {
521+
std::unique_ptr<ObjectStore> CAS = createInMemoryCAS();
522+
ASSERT_TRUE(CAS);
523+
std::optional<ObjectProxy> Tree;
524+
ASSERT_THAT_ERROR(createNestedTree(*CAS).moveInto(Tree), Succeeded());
525+
std::unique_ptr<vfs::FileSystem> CASFS;
526+
ASSERT_THAT_ERROR(createFS(*CAS, *Tree).moveInto(CASFS), Succeeded());
527+
528+
{
529+
std::string FSStr;
530+
llvm::raw_string_ostream OS(FSStr);
531+
CASFS->print(OS, vfs::FileSystem::PrintType::Summary);
532+
EXPECT_EQ(FSStr, "CASFileSystem\n");
533+
}
534+
{
535+
std::string FSStr;
536+
llvm::raw_string_ostream OS(FSStr);
537+
CASFS->print(OS, vfs::FileSystem::PrintType::Contents);
538+
std::string Expected = "CASFileSystem\n";
539+
Expected += " root: / " + Tree->getID().toString() + "\n";
540+
EXPECT_EQ(FSStr, Expected);
541+
}
542+
{
543+
std::string FSStr;
544+
llvm::raw_string_ostream OS(FSStr);
545+
CASFS->print(OS, vfs::FileSystem::PrintType::RecursiveContents);
546+
std::string Expected = "CASFileSystem\n";
547+
Expected += " root: / " + Tree->getID().toString() + "\n";
548+
StringRef Printed(FSStr);
549+
EXPECT_TRUE(Printed.consume_front("CASFileSystem")) << Printed;
550+
EXPECT_TRUE(Printed.consume_front("\n root: / llvmcas://")) << Printed;
551+
Printed = Printed.drop_front(64); // 32 hash bytes in hex
552+
EXPECT_TRUE(Printed.consume_front("\n file llvmcas://")) << Printed;
553+
Printed = Printed.drop_front(64); // 32 hash bytes in hex
554+
EXPECT_TRUE(Printed.consume_front(" /d2")) << Printed;
555+
EXPECT_TRUE(Printed.consume_front("\n file llvmcas://")) << Printed;
556+
Printed = Printed.drop_front(64); // 32 hash bytes in hex
557+
EXPECT_TRUE(Printed.consume_front(" /t1/d1\n")) << Printed;
558+
// ...
559+
EXPECT_TRUE(Printed.consume_back("/t3/t2/d2\n")) << Printed;
560+
}
561+
}

0 commit comments

Comments
 (0)