Fix .dirindex preservation on Windows

Ensure we don't treat the special files as regular children
when updating.
This commit is contained in:
James Turner
2018-07-18 16:30:44 +01:00
parent 3dfce43de2
commit a0c4913f84
2 changed files with 44 additions and 16 deletions

View File

@@ -323,32 +323,35 @@ public:
toBeUpdated, orphans;
simgear::Dir d(absolutePath());
PathList fsChildren = d.children(0);
PathList::const_iterator it = fsChildren.begin();
for (; it != fsChildren.end(); ++it) {
ChildInfo info(it->isDir() ? ChildInfo::DirectoryType : ChildInfo::FileType,
it->file(), "");
for (const auto& child : fsChildren) {
const auto& fileName = child.file();
if ((fileName == ".dirindex") || (fileName == ".hashes")) {
continue;
}
ChildInfo info(child.isDir() ? ChildInfo::DirectoryType : ChildInfo::FileType, fileName, "");
std::string hash = hashForChild(info);
ChildInfoList::iterator c = findIndexChild(it->file());
ChildInfoList::iterator c = findIndexChild(fileName);
if (c == children.end()) {
orphans.push_back(it->file());
orphans.push_back(fileName);
} else if (c->hash != hash) {
#if 0
SG_LOG(SG_TERRASYNC, SG_DEBUG, "hash mismatch'" << it->file() );
SG_LOG(SG_TERRASYNC, SG_DEBUG, "hash mismatch'" << fileName);
// file exists, but hash mismatch, schedule update
if (!hash.empty()) {
SG_LOG(SG_TERRASYNC, SG_DEBUG, "file exists but hash is wrong for:" << it->file() );
SG_LOG(SG_TERRASYNC, SG_DEBUG, "file exists but hash is wrong for:" << fileName);
SG_LOG(SG_TERRASYNC, SG_DEBUG, "on disk:" << hash << " vs in info:" << c->hash);
}
#endif
toBeUpdated.push_back(it->file() );
toBeUpdated.push_back(fileName);
} else {
// file exists and hash is valid. If it's a directory,
// perform a recursive check.
if (c->type == ChildInfo::DirectoryType) {
HTTPDirectory* childDir = childDirectory(it->file());
HTTPDirectory* childDir = childDirectory(fileName);
childDir->updateChildrenBasedOnHash();
}
}
@@ -356,7 +359,7 @@ public:
// remove existing file system children from the index list,
// so we can detect new children
// https://en.wikibooks.org/wiki/More_C%2B%2B_Idioms/Erase-Remove
indexNames.erase(std::remove(indexNames.begin(), indexNames.end(), it->file()), indexNames.end());
indexNames.erase(std::remove(indexNames.begin(), indexNames.end(), fileName), indexNames.end());
} // of real children iteration
// all remaining names in indexChilden are new children
@@ -824,7 +827,7 @@ HTTPRepository::failure() const
// dir index data has changed, so write to disk and update
// the hash accordingly
sg_ofstream of(pathInRepo(), std::ios::trunc | std::ios::out);
sg_ofstream of(pathInRepo(), std::ios::trunc | std::ios::out | std::ios::binary);
if (!of.is_open()) {
throw sg_io_exception("Failed to open directory index file for writing", pathInRepo());
}

View File

@@ -437,6 +437,34 @@ void testBasicClone(HTTP::Client* cl)
std::cout << "Passed test: basic clone and update" << std::endl;
}
void testUpdateNoChanges(HTTP::Client* cl)
{
std::unique_ptr<HTTPRepository> repo;
SGPath p(simgear::Dir::current().path());
p.append("http_repo_basic"); // same as before
global_repo->clearRequestCounts();
repo.reset(new HTTPRepository(p, cl));
repo->setBaseUrl("http://localhost:2000/repo");
repo->update();
waitForUpdateComplete(cl, repo.get());
verifyFileState(p, "fileA");
verifyFileState(p, "dirC/subdirA/subsubA/fileCAAA");
verifyRequestCount("dirA", 0);
verifyRequestCount("dirB", 0);
verifyRequestCount("dirB/subdirA", 0);
verifyRequestCount("dirB/subdirA/fileBAA", 0);
verifyRequestCount("dirC", 0);
verifyRequestCount("dirC/fileCA", 0);
std::cout << "Passed test:no changes update" << std::endl;
}
void testModifyLocalFiles(HTTP::Client* cl)
{
std::unique_ptr<HTTPRepository> repo;
@@ -473,10 +501,6 @@ void testModifyLocalFiles(HTTP::Client* cl)
std::cout << "Passed test: identify and fix locally modified files" << std::endl;
}
void testNoChangesUpdate()
{
}
void testMergeExistingFileWithoutDownload(HTTP::Client* cl)
{
@@ -755,6 +779,7 @@ int main(int argc, char* argv[])
global_repo->defineFile("dirC/subdirA/subsubA/fileCAAA");
testBasicClone(&cl);
testUpdateNoChanges(&cl);
testModifyLocalFiles(&cl);