Skip to content

Commit f73b84b

Browse files
authored
Merge pull request #501 from dmbryson/dcfix-5.1
Cherry-pick 'Handle SkippedCommand values in DirectoryContents'
2 parents a75c546 + 1808e05 commit f73b84b

File tree

2 files changed

+96
-1
lines changed

2 files changed

+96
-1
lines changed

Diff for: lib/BuildSystem/BuildSystem.cpp

+8-1
Original file line numberDiff line numberDiff line change
@@ -880,6 +880,13 @@ class DirectoryContentsTask : public Task {
880880
return;
881881
}
882882

883+
// The input directory may be a 'mkdir' command, which can be cancelled or
884+
// skipped by the engine or the delegate. rdar://problem/50380532
885+
if (directoryValue.isSkippedCommand()) {
886+
engine.taskIsComplete(this, BuildValue::makeSkippedCommand().toData());
887+
return;
888+
}
889+
883890
std::vector<std::string> filenames;
884891
getContents(path, filenames);
885892

@@ -1294,7 +1301,7 @@ class DirectoryTreeStructureSignatureTask : public Task {
12941301

12951302
// Request the inputs for each subpath.
12961303
auto value = BuildValue::fromData(valueData);
1297-
if (value.isMissingInput())
1304+
if (value.isMissingInput() || value.isSkippedCommand())
12981305
return;
12991306

13001307
assert(value.isDirectoryContents());

Diff for: unittests/BuildSystem/BuildSystemTaskTests.cpp

+88
Original file line numberDiff line numberDiff line change
@@ -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

Comments
 (0)