Repository: conan-io/conan

Issue:
Versioning the format of the lockfile?
@memsharded 
I think we should add a field to a generated lockfile with the version, for example "0.1". 
I'm not thinking about making Conan compatible with older lockfiles necessarily, but it might be useful to:

 - Fail accordingly if the format is not supported.
 - Maybe other tools (I'm thinking about jfrog-cli and build-info, if maybe it could leverage from the lockfiles for a better build-info), but they will need to know the input format-version. (Very preliminary thoughts)
 
This is pretty speculative but I think it is real enough and cheap to introduce just a field. WDYT?



Discussion:

Resolving patch:
diff --git a/conans/model/graph_lock.py b/conans/model/graph_lock.py
--- a/conans/model/graph_lock.py
+++ b/conans/model/graph_lock.py
@@ -8,9 +8,11 @@
 from conans.model.options import OptionsValues
 from conans.model.ref import PackageReference, ConanFileReference
 from conans.util.files import load, save
+from conans.model.version import Version
 
 
 LOCKFILE = "conan.lock"
+LOCKFILE_VERSION = "0.1"
 
 
 class GraphLockFile(object):
@@ -37,6 +39,10 @@ def load(path):
     @staticmethod
     def loads(text):
         graph_json = json.loads(text)
+        version = graph_json.get("version")
+        if version:
+            version = Version(version)
+            # Do something with it, migrate, raise...
         profile = graph_json["profile"]
         # FIXME: Reading private very ugly
         profile, _ = _load_profile(profile, None, None)
@@ -52,7 +58,8 @@ def save(self, path):
 
     def dumps(self):
         result = {"profile": self.profile.dumps(),
-                  "graph_lock": self.graph_lock.as_dict()}
+                  "graph_lock": self.graph_lock.as_dict(),
+                  "version": LOCKFILE_VERSION}
         return json.dumps(result, indent=True)
 
 


Test patch:
diff --git a/conans/test/functional/graph_lock/graph_lock_ci_test.py b/conans/test/functional/graph_lock/graph_lock_ci_test.py
--- a/conans/test/functional/graph_lock/graph_lock_ci_test.py
+++ b/conans/test/functional/graph_lock/graph_lock_ci_test.py
@@ -1,3 +1,4 @@
+import json
 import os
 import textwrap
 import unittest
@@ -6,7 +7,6 @@
 from conans.test.utils.tools import TestClient, TestServer
 from conans.util.files import load
 from conans.model.ref import PackageReference
-import json
 
 
 class GraphLockCITest(unittest.TestCase):
diff --git a/conans/test/functional/graph_lock/graph_lock_test.py b/conans/test/functional/graph_lock/graph_lock_test.py
--- a/conans/test/functional/graph_lock/graph_lock_test.py
+++ b/conans/test/functional/graph_lock/graph_lock_test.py
@@ -3,10 +3,10 @@
 import textwrap
 import unittest
 
+from conans.model.graph_lock import LOCKFILE, LOCKFILE_VERSION
+from conans.test.utils.conanfile import TestConanFile
 from conans.test.utils.tools import TestClient, TestServer
 from conans.util.files import load
-from conans.test.utils.conanfile import TestConanFile
-from conans.model.graph_lock import LOCKFILE
 
 
 class GraphLockErrorsTest(unittest.TestCase):
@@ -36,6 +36,7 @@ class GraphLockCustomFilesTest(unittest.TestCase):
     def _check_lock(self, ref_b, rev_b=""):
         lock_file = load(os.path.join(self.client.current_folder, "custom.lock"))
         lock_file_json = json.loads(lock_file)
+        self.assertEqual(lock_file_json["version"], LOCKFILE_VERSION)
         self.assertEqual(2, len(lock_file_json["graph_lock"]["nodes"]))
         self.assertIn("PkgA/0.1@user/channel#b55538d56afb03f068a054f11310ce5a:"
                       "5ab84d6acfe1f23c4fae0ab88f26e3a396351ac9#6d56ca1040e37a13b75bc286f3e1a5ad",