Warn if an import contains multiple occurrences of the same UUID (#3560)

This commit is contained in:
Adrian Sadłocha 2024-07-20 03:27:16 +01:00 committed by GitHub
parent 0650fe509f
commit 7ea4baed77
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 28 additions and 1 deletions

View file

@ -32,6 +32,7 @@
#include <format.h>
#include <shared.h>
#include <util.h>
#include <unordered_map>
////////////////////////////////////////////////////////////////////////////////
CmdImport::CmdImport ()
@ -90,6 +91,20 @@ int CmdImport::execute (std::string&)
}
Context::getContext ().footnote (format ("Imported {1} tasks.", count));
// Warn the user about multiple occurrences of the same UUID.
auto duplicates = false;
for (const auto& [uuid, occurrences] : uuid_occurrences)
{
if (occurrences > 1)
{
duplicates = true;
Context::getContext ().footnote (format ("Input contains UUID '{1}' {2} times.", uuid, occurrences));
}
}
if (duplicates)
Context::getContext ().footnote ("Tasks with the same UUID have been merged. Please check the results.");
return rc;
}
@ -186,7 +201,9 @@ void CmdImport::importSingleTask (json::object* obj)
// Check whether the imported task is new or a modified existing task.
Task before;
if (Context::getContext ().tdb2.get (task.get ("uuid"), before))
auto uuid = task.get("uuid");
uuid_occurrences[uuid]++;
if (Context::getContext ().tdb2.get (uuid, before))
{
// We need to neglect updates from attributes with dynamic defaults
// unless they have been explicitly specified on import.

View file

@ -38,6 +38,7 @@ public:
int execute (std::string&);
private:
std::unordered_map<std::string, unsigned int> uuid_occurrences;
int import (const std::string&);
void importSingleTask (json::object*);
};

View file

@ -224,6 +224,15 @@ class TestImport(TestCase):
code, out2, err = self.t("export")
self.assertEqual(out1, out2)
def test_import_duplicate_uuid_in_input(self):
"""Test import warns if input contains the same UUID twice."""
_data = """[
{"uuid":"a0000000-a000-a000-a000-a00000000000","description":"first description"},
{"uuid":"a0000000-a000-a000-a000-a00000000000","description":"second description"}
]"""
_, _, err = self.t("import", input=_data)
self.assertIn("Input contains UUID 'a0000000-a000-a000-a000-a00000000000' 2 times", err)
class TestImportExportRoundtrip(TestCase):
def setUp(self):