CORD-2741 implement VERSION file discovery for xos python libraries

Change-Id: Ife67b0066d5fd54958e1b1de3c5b3758ac9d3ca6
diff --git a/lib/xos-util/xosutil/autodiscover_version.py b/lib/xos-util/xosutil/autodiscover_version.py
new file mode 100644
index 0000000..023aa79
--- /dev/null
+++ b/lib/xos-util/xosutil/autodiscover_version.py
@@ -0,0 +1,51 @@
+
+# Copyright 2017-present Open Networking Foundation
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+"""
+   xosutil/autodiscover_version.py
+
+   This module implements support for recursively searching for a VERSION file and extracting the version number from
+   it. Search starts from the directory of this file, or if autodiscover_version_of_caller is called, the directory
+   of the caller.
+"""
+
+import inspect
+import os
+
+def autodiscover_version(caller_filename=None, save_to=None):
+    """ walk back along the path to the current module, searching for a VERSION file """
+    if not caller_filename:
+        caller_filename = os.path.realpath(__file__)
+    file_path = os.path.abspath(os.path.dirname(caller_filename))
+    cur_path = file_path
+    while True:
+        version_fn = os.path.join(cur_path, "VERSION")
+        if os.path.exists(version_fn):
+            version = open(version_fn, "rt").readline().strip()
+            if save_to:
+                f = open(os.path.join(file_path, save_to), "wt")
+                f.write("# This file is autogenerated. Do not edit.\n")
+                f.write("__version__ = '%s'\n" % version)
+                f.close()
+            return version
+
+        (cur_path, remainder) = os.path.split(cur_path)
+        if not remainder:
+            return None
+
+def autodiscover_version_of_caller(*args, **kwargs):
+    frame = inspect.stack()[1]
+    module = inspect.getmodule(frame[0])
+    return autodiscover_version(module.__file__, *args, **kwargs)