From a0c4913f84e8b2581f9a6298344f3e888e9e6c5e Mon Sep 17 00:00:00 2001 From: James Turner Date: Wed, 18 Jul 2018 16:30:44 +0100 Subject: [PATCH] Fix .dirindex preservation on Windows Ensure we don't treat the special files as regular children when updating. --- simgear/io/HTTPRepository.cxx | 27 +++++++++++++++------------ simgear/io/test_repository.cxx | 33 +++++++++++++++++++++++++++++---- 2 files changed, 44 insertions(+), 16 deletions(-) diff --git a/simgear/io/HTTPRepository.cxx b/simgear/io/HTTPRepository.cxx index acac1cf8..fb2cd9fe 100644 --- a/simgear/io/HTTPRepository.cxx +++ b/simgear/io/HTTPRepository.cxx @@ -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()); } diff --git a/simgear/io/test_repository.cxx b/simgear/io/test_repository.cxx index 666ff5c9..0148fc5c 100644 --- a/simgear/io/test_repository.cxx +++ b/simgear/io/test_repository.cxx @@ -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 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 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);