From c898a4ca9e5de683b5e92a362675704f41b05f86 Mon Sep 17 00:00:00 2001
From: Pawel Szostek <pawel.szostek@cern.ch>
Date: Mon, 21 Oct 2013 21:55:18 +0200
Subject: [PATCH] correct git submodules treatment

---
 hdlmake/action/simulation.py |  2 +-
 hdlmake/fetch/git.py         | 66 +++++++++++++++++++++++++++---------
 hdlmake/module.py            | 21 ++++++++----
 3 files changed, 65 insertions(+), 24 deletions(-)

diff --git a/hdlmake/action/simulation.py b/hdlmake/action/simulation.py
index 26163849..6ac3f977 100644
--- a/hdlmake/action/simulation.py
+++ b/hdlmake/action/simulation.py
@@ -49,7 +49,7 @@ class GenerateSimulationMakefile(Action):
             self._generate_vsim_makefile()
             logging.info("Generating simulation makefile for vsim")
         else:
-            logging.error("Unrecognized or not specified simulation tool: %s" % str(tm.sim_tool))
+            logging.error("Unrecognized or not specified simulation tool: %s\nPlease set sim_tool in the top manifest." % str(tm.sim_tool))
             sys.exit("Exiting")
         logging.info("Simulation makefile generated.")
 
diff --git a/hdlmake/fetch/git.py b/hdlmake/fetch/git.py
index d44d65c0..2ba6c581 100644
--- a/hdlmake/fetch/git.py
+++ b/hdlmake/fetch/git.py
@@ -43,6 +43,22 @@ class Git(Fetcher):
     def __init__(self):
         pass
 
+    @staticmethod
+    def get_git_toplevel(module):
+        cur_dir = os.getcwd()
+        try:
+            os.chdir(path.rel2abs(module.path))
+            if not os.path.exists(".gitmodules"):
+                return None
+            tree_root_cmd = Popen("git rev-parse --show-toplevel",
+                              stdout=PIPE,
+                              stdin=PIPE,
+                              shell=True)
+            tree_root_line = tree_root_cmd.stdout.readlines()[0].strip()
+            return tree_root_line
+        finally:
+            os.chdir(cur_dir)
+
     @staticmethod
     def get_git_submodules(module):
         submodule_dir = path.rel2abs(module.path)
@@ -51,31 +67,49 @@ class Git(Fetcher):
         try:
             os.chdir(submodule_dir)
 
+            if not os.path.exists(".gitmodules"):
+                return {}
             #"git config --list" | grep submodule | sed 's/.*=//')" % submodule_dir
-            config_content = Popen("git config --list",
+            config_submodules = {}
+            config_content = Popen("git config -f .gitmodules --list",
                                       stdout=PIPE,
                                       stdin=PIPE,
                                       shell=True)
             config_lines = [line.strip() for line in config_content.stdout.readlines()]
-            config_submodule_lines = [line for line in config_lines if "submodule" in line]
-            config_submodules = [line.split("=")[-1] for line in config_submodule_lines]
+            """try to parse sth like this:
+paszoste@oplarra1:~/beco/hdlmake-tests/wr-switch-hdl$ git config -f .gitmodules --list
+submodule.ip_cores/general-cores.path=ip_cores/general-cores
+submodule.ip_cores/general-cores.url=git://ohwr.org/hdl-core-lib/general-cores.git
+submodule.ip_cores/wr-cores.path=ip_cores/wr-cores
+submodule.ip_cores/wr-cores.url=git://ohwr.org/hdl-core-lib/wr-cores.git
+"""
+            config_submodule_lines = [line for line in config_lines if line.startswith("submodule")]
+            for line in config_submodule_lines:
+                line_split = line.split("=")
+                lhs = line_split[0]
+                rhs = line_split[1]
+                lhs_split = lhs.split(".")
+                module_name = '.'.join(lhs_split[1:-1])
+                if module_name not in config_submodules:
+                    config_submodules[module_name] = {}
+                config_submodules[module_name][lhs_split[-1]] = rhs
+
 
             #"(cd %s && cat ./.gitmodules 2>/dev/null | grep url | sed 's/url = //')" % submodule_dir
-            try:
-                dotgitmodules_file = open(".gitmodules", 'r')
-                dotgitmodules_lines = dotgitmodules_file.readlines()
-                url_lines = [line for line in dotgitmodules_lines if 'url' in line]
-                dotgitmodules_submodules = [line.split(" = ")[-1].strip() for line in url_lines]
-
-                set(config_submodules).update(set(dotgitmodules_submodules))
-            except IOError:
-                pass  # no .gitmodules file
-            submodules = list(config_submodules)
-            if len(submodules) > 0:
-                logging.info("Found git submodules in %s" % module.path)
+            #try:
+            ##    dotgitmodules_file = open(".gitmodules", 'r')
+             #   dotgitmodules_lines = dotgitmodules_file.readlines()
+             #   url_lines = [line for line in dotgitmodules_lines if 'url' in line]
+             #   dotgitmodules_submodules = [line.split(" = ")[-1].strip() for line in url_lines]
+
+             #  set(config_submodules).update(set(dotgitmodules_submodules))
+            #except IOError:
+             #   pass  # no .gitmodules file
+            if len(list(config_submodules)) > 0:
+                logging.info("Found git submodules in %s: %s" % (module.path, str(config_submodules)))
         finally:
             os.chdir(cur_dir)
-        return submodules
+        return config_submodules
 
     def fetch(self, module):
         if module.source != fetch.GIT:
diff --git a/hdlmake/module.py b/hdlmake/module.py
index 19fb3256..fd18c23d 100644
--- a/hdlmake/module.py
+++ b/hdlmake/module.py
@@ -112,9 +112,11 @@ class Module(object):
             if os.path.exists(os.path.abspath(os.path.join(fetchto, self.basename))):
                 self.path = os.path.abspath(os.path.join(fetchto, self.basename))
                 self.isfetched = True
+                logging.debug("Module %s (parent: %s) is fetched." % (url, parent.path))
             else:
                 self.path = None
                 self.isfetched = False
+                logging.debug("Module %s (parent: %s) is NOT fetched." % (url, parent.path))
 
         self.manifest = None
 
@@ -226,9 +228,9 @@ class Module(object):
         if self.isprocessed is True:
             return
         if self.manifest_dict is None:
-            logging.debug("there is no manifest to be processed")
+            logging.debug("There is no manifest to be processed in: %s" % self.url)
             return
-        logging.debug(self.path)
+        logging.debug("Process manifest in: %s" % self.path)
         if self.manifest_dict["syn_ise_version"] is not None:
             version = self.manifest_dict["syn_ise_version"]
             self.syn_ise_version = str(version)
@@ -316,7 +318,7 @@ class Module(object):
                 pass
         else:
             self.manifest_dict["files"] = self._flatten_list(self.manifest_dict["files"])
-            logging.debug(self.path + str(self.manifest_dict["files"]))
+            logging.debug("Files in %s: %s" % (self.path, str(self.manifest_dict["files"])))
             paths = self._make_list_of_paths(self.manifest_dict["files"])
             self.files = self._create_file_list_from_paths(paths=paths)
             for f in self.files:
@@ -366,11 +368,16 @@ class Module(object):
         else:
             self.git = []
 
-        git_submodule_urls = fetch.Git.get_git_submodules(self)
-        for submodule_url in git_submodule_urls:
+        git_submodule_dict = fetch.Git.get_git_submodules(self)
+        git_toplevel = fetch.Git.get_git_toplevel(self)
+        for submodule_key in git_submodule_dict.keys():
+            url = git_submodule_dict[submodule_key]["url"]
+            path = git_submodule_dict[submodule_key]["path"]
+            path = os.path.join(git_toplevel, path)
+            fetchto = os.path.sep.join(path.split(os.path.sep)[:-1])
             self.git_submodules.append(self.pool.new_module(parent=self,
-                                                            url=submodule_url,
-                                                            fetchto=self.path,
+                                                            url=url,
+                                                            fetchto=fetchto,
                                                             source=fetch.GITSUBMODULE))
         self.target = self.manifest_dict["target"].lower()
         self.action = self.manifest_dict["action"].lower()
-- 
GitLab