@@ -1078,3 +1078,91 @@ TEST(BuildSystemTaskTests, producedNodeAfterPreviouslyMissing) {
10781078 ASSERT_TRUE (!afterFileInfo.isMissing ());
10791079 }
10801080}
1081+
1082+ // / Check that directory contents properly handles when commands have been
1083+ // / skipped. rdar://problem/50380532
1084+ TEST (BuildSystemTaskTests, directoryContentsWithSkippedCommand) {
1085+ TmpDir tempDir (__func__);
1086+
1087+ SmallString<256 > manifest{ tempDir.str () };
1088+ for (auto & c : manifest) {
1089+ if (c == ' \\ ' )
1090+ c = ' /' ;
1091+ }
1092+ sys::path::append (manifest, " manifest.llbuild" );
1093+
1094+
1095+ {
1096+ std::error_code ec;
1097+ llvm::raw_fd_ostream os (manifest, ec, llvm::sys::fs::F_Text);
1098+ assert (!ec);
1099+
1100+ os <<
1101+ " client:\n "
1102+ " name: mock\n "
1103+ " \n "
1104+ " targets:\n "
1105+ " \"\" : [\" <all>\" ]\n "
1106+ " \n "
1107+ " commands:\n "
1108+ " \" mkdir-inputDir\" :\n "
1109+ " tool: mkdir\n "
1110+ " outputs: [\" inputDir\" ]\n "
1111+ " \" read-inputDir\" :\n "
1112+ " tool: shell\n "
1113+ " inputs: [\" inputDir/\" ]\n "
1114+ " outputs: [\" read-inputDir\" ]\n "
1115+ " description: \" read-inputDir\"\n "
1116+ " args:\n "
1117+ " touch read-inputDir\n "
1118+ " \" <all>\" :\n "
1119+ " tool: phony\n "
1120+ " inputs: [\" read-inputDir\" ]\n "
1121+ " outputs: [\" <all>\" ]" ;
1122+ }
1123+
1124+ class CancellingDelegate : public MockBuildSystemDelegate {
1125+ public:
1126+ BuildSystem* system = nullptr ;
1127+
1128+ CancellingDelegate (): MockBuildSystemDelegate() { }
1129+
1130+ virtual bool shouldCommandStart (Command* command) override {
1131+ if (command->getName () == " mkdir-inputDir" ) {
1132+ return false ;
1133+ }
1134+ return true ;
1135+ }
1136+ };
1137+
1138+ // Create the build system.
1139+ CancellingDelegate delegate;
1140+ BuildSystem system (delegate, createLocalFileSystem ());
1141+ delegate.system = &system;
1142+ bool loadingResult = system.loadDescription (manifest);
1143+ ASSERT_TRUE (loadingResult);
1144+
1145+ // Build the default target
1146+ auto result = system.build (BuildKey::makeTarget (" " ));
1147+ ASSERT_TRUE (result.hasValue ());
1148+
1149+ // The contents should propagate the skipped command
1150+ result = system.build (BuildKey::makeDirectoryContents (" inputDir" ));
1151+ ASSERT_TRUE (result.hasValue ());
1152+ ASSERT_TRUE (result.getValue ().isSkippedCommand ());
1153+
1154+ // Signatures don't need the contents and should be fine with encoding the
1155+ // skipped value in the signature.
1156+ result = system.build (BuildKey::makeDirectoryTreeSignature (" inputDir" , {}));
1157+ ASSERT_TRUE (result.hasValue ());
1158+ ASSERT_FALSE (result.getValue ().isSkippedCommand ());
1159+
1160+ auto filters = StringList ({" filter" });
1161+ result = system.build (BuildKey::makeDirectoryTreeSignature (" inputDir" , filters));
1162+ ASSERT_TRUE (result.hasValue ());
1163+ ASSERT_FALSE (result.getValue ().isSkippedCommand ());
1164+
1165+ result = system.build (BuildKey::makeDirectoryTreeStructureSignature (" inputDir" ));
1166+ ASSERT_TRUE (result.hasValue ());
1167+ ASSERT_FALSE (result.getValue ().isSkippedCommand ());
1168+ }
0 commit comments