Commits

Anonymous committed a6239ab

Fully implemented repo updating.

  • Participants
  • Parent commits b5cb150

Comments (0)

Files changed (1)

 
 
 def note(message):
-    print(message),
+    print('\t' + message),
     #ui.note(message)
 
 def warn(message):
-    print(message),
+    print('\t' + message),
     #ui.warn(message)
 
+def debug(message):
+    print('\t' + message),
+    #ui.debug(message)
+
 def ClassifyRepo(ui, repo):
-    repoNew = False
     repoClass = 'Regular'
-
-    depFilePath = repo.root + '/' + depFileName;
-    revFilePath = repo.root + '/' + revFileName;
-    mapFilePath = repo.root + '/' + mapFileName; 
+    depFilePath = GetRepoDependencyFilePath(repo)
+    revFilePath = GetRepoReverseDependencyFilePath(repo)
+    mapFilePath = GetRepoMapDependencyFilePath(repo)
     
     # If this repo has a file called '.hgdep' at its root,
     # it is a dep repo.
     if os.path.isfile(depFilePath):
         # Determine if the dep repo is the root repo or a module
         if os.path.isfile(revFilePath):
-            note("Module - ")
+            note("Module\n")
             repoClass = 'Module'
-            # Determine if this is the initial update (clone) of this module 
-            if not os.path.isfile(mapFilePath):
-                repoNew = True
         else:
-            note("Root - ")
+            note("Root\n")
             repoClass = 'Root'
-            # Determine if this is the initial update (clone) of this root
-            if not os.path.isfile(mapFilePath):
-                repoNew = True
     elif os.path.isfile(revFilePath):
-        note("Leaf Module - ")
+        note("Leaf Module\n")
         repoClass = 'LeafModule'
-        # Determine if this is the initial update (clone) of this module
-        if os.path.getsize(revFilePath) <= 0:
-            repoNew = True
 
-    if repoClass != 'Regular':        
-        if repoNew == True:
-            note("New\n")
-        else:
-            note("Existing\n")
+    return repoClass
 
-    return repoClass, repoNew
+def GetRepoDependencyFilePath(repo):
+    return "%s/%s" % (repo.root, depFileName)
 
+def GetRepoReverseDependencyFilePath(repo):
+    return "%s/%s" % (repo.root, revFileName)
+
+def GetRepoMapDependencyFilePath(repo):
+    return "%s/%s" % (repo.root, mapFileName)
     
 def GetModuleList(rootFilePath):
+    note("Getting dependency group module list\n")
     with open(rootFilePath,'r+') as rootFile:
         moduleAliases = []
         moduleSourcePaths = []
 
     return dependentPaths
 
+def GetDependencyList(depFilePath):
+    with open(depFilePath,'r') as depFile:
+        dependencyAliases = []
+        dependencySourcePaths = []
+        dependencyChangesets = []
+        for line in depFile.readlines():
+            depInfo = line.split(' ', 2)
+            if len(depInfo) == 3:
+                dependencyAliases.append(depInfo[0].strip())
+                dependencySourcePaths.append(depInfo[1].strip())
+                dependencyChangesets.append(depInfo[2].strip())
+
+    return dependencyAliases, dependencySourcePaths, dependencyChangesets
+
+
 def AppendToRootFile(rootFilePath, alias, sourcePath, changeset):
     with open(rootFilePath,'r+') as rootFile:
         rootFile = open(rootFilePath,'a')
         rootFile.write("%s %s %s\n" % (alias, sourcePath, changeset))
 
 def GetChangeContextShortID(changeContext):
-    return changeContext.hex()[0:12]            
+    return changeContext.hex()[0:12] 
 
-def UpdateNewDepGroupRepo(ui, repo, repoClass):
+def GetRootFileAndModuleDirectoryPaths(repo, repoClass):
+    if repoClass == 'Root':
+        moduleDirectoryPath = '%s/modules' % repo.root
+        rootFilePath = '%s/%s' % (repo.root, rootFileName)
+    else:
+        moduleDirectoryPath = '%s/..' % repo.root
+        rootFilePath = '%s/../../%s' % (repo.root, rootFileName)
+
+    return rootFilePath, moduleDirectoryPath
+
+def AddDependency(ui, repo, repoClass):
     if repoClass == 'Root' or repoClass == 'Module':
-        if repoClass == 'Root':
-            modulePath = repo.root + '/modules'
-            rootFilePath = repo.root + '/' + rootFileName
-            if not os.path.exists(modulePath):
-                os.makedirs(modulePath)
-            open(rootFilePath, 'w').close()
-            #AppendToRootFile(rootFilePath, "root", "root", GetChangeContextShortID(repo['.']))
-        else:
-            modulePath = repo.root + '/..'
-            rootFilePath = repo.root + '/../../' + rootFileName
+        note("Adding dependencies for Dependency Group repo at %s\n" % repo.root)
+        
+        rootFilePath, modulePath = GetRootFileAndModuleDirectoryPaths(repo, repoClass)
 
         # Parse this repo's '.hgdep' file
-        depFilePath = repo.root + '/' + depFileName
-        with open(depFilePath,'r') as depFile:
+        depFilePath = GetRepoDependencyFilePath(repo)
+        dependencyAliases, dependencySourcePaths, dependencyChangesets = GetDependencyList(depFilePath)
 
-            mapFilePath = repo.root + '/' + mapFileName
-            with open(mapFilePath,'a') as mapFile:
+        # For each dependency
+        for depIndex, depChangeset in enumerate(dependencyChangesets):
+            note("Found dependency on %s %s\n" % (dependencySourcePaths[depIndex], depChangeset))
+            # Parse the root's '.hgdeproot' file so we can detect
+            # redundant dependencies.
+            # Note, we need to do this within the depFile loop
+            # because this function is recursive, which means the
+            # root file could change before the next iteration of
+            # this loop occurs.
+            moduleAliases, moduleSourcePaths, moduleChangesets = GetModuleList(rootFilePath)
 
-                # For each line, get the repo alias, source, and changeset
-                for line in depFile.readlines():
 
-                    # Parse the root's '.hgdeproot' file so we can detect
-                    # redundant dependencies.
-                    # Note, we need to do this within the depFile loop
-                    # because this function is recursive, which means the
-                    # root file could change before the next iteration of
-                    # this loop occurs.
-                    moduleAliases, moduleSourcePaths, moduleChangesets = GetModuleList(rootFilePath)
+            # Try to determine if the requested dependency is 
+            # already in the depedency group
+            repeatModule = False
+            for index, moduleChangeset in enumerate(moduleChangesets):
+                if (depChangeset == moduleChangeset):
+                    folderPath = modulePath + '/%s' % moduleAliases[index]
+                    repeatModule = True
+                    note("%s %s already exists in dependency group as %s\n" % (dependencySourcePaths[depIndex], depChangeset, moduleAliases[index]))
+                    break
 
-                    depInfo = line.split(' ', 2)
-                    if len(depInfo) == 3:
-                        alias = depInfo[0].strip()
-                        sourcePath = depInfo[1].strip()
-                        changeset = depInfo[2].strip()
+            # If this is a new module, bring it into the dependency group.
+            if repeatModule == False:
 
-                        # Try to determine if the requested dependency is 
-                        # already in the depedency group
-                        repeatModule = False
-                        for index, moduleChangeset in enumerate(moduleChangesets):
-                            if (changeset == moduleChangeset):
-                                folderPath = modulePath + '/%s' % moduleAliases[index]
-                                repeatModule = True
-                                break
+                # Find a suitable alias name.
+                # Default to the name the dependent repo has for the module.
+                newAliasName = dependencyAliases[depIndex]
 
-                        # If this is a new module, bring it into the dependency group.
-                        if repeatModule == False:
+                # If another module has already been added with the same
+                # alias, we simply tack on a increment until we achieve
+                # a unique name.
+                count = 1
+                while newAliasName in moduleAliases:
+                    newAliasName = dependencyAliases[depIndex] + '%d' % count
+                    count = count + 1
 
-                            # Find a suitable alias name.
-                            # Default to the name the dependent repo has for the module.
-                            newAliasName = alias
+                note("Creating module %s for %s %s\n" % (newAliasName, dependencySourcePaths[depIndex], depChangeset))
 
-                            # If another module has already been added with the same
-                            # alias, we simply tack on a increment until we achieve
-                            # a unique name.
-                            count = 1
-                            while newAliasName in moduleAliases:
-                                newAliasName = alias + '%d' % count
-                                print(newAliasName)
-                                count = count + 1
+                # Create repo for module
+                folderPath = "%s/%s" % (modulePath, newAliasName)
+                commands.init(ui, folderPath)
+                moduleRepo = hg.repository(ui, folderPath)
 
-                            # Create repo for module
-                            folderPath = modulePath + '/%s' % newAliasName
-                            commands.init(ui, folderPath)
-                            moduleRepo = hg.repository(ui, folderPath)
+                # The order here is very important!
+                # We must create the reverse dependency file BEFORE
+                # pulling and updating the module repo or it could think
+                # it's its own root repo.
+                # Therefore, we open here to create the file.  We write to it later.
+                open(folderPath + '/' + revFileName, 'w').close()
 
-                            # The order here is very important!
-                            # We must create the reverse dependency file BEFORE
-                            # pulling and updating the module repo or it could think
-                            # it's its own root repo.  HOWEVER, we must not yet write
-                            # to the reverse dependecy file, because leaf modules use
-                            # and empty reverse dependency file to determine they are new.
-                            # Therefore, we open here to create the file.  We write to it later.
-                            open(folderPath + '/' + revFileName, 'w').close()
+                AppendToRootFile(rootFilePath, newAliasName, dependencySourcePaths[depIndex], depChangeset)
 
-                            AppendToRootFile(rootFilePath, newAliasName, sourcePath, changeset)
+                # Pull the module in
+                commands.pull(ui, moduleRepo, source=dependencySourcePaths[depIndex])
+                commands.update(ui, moduleRepo, moduleRepo[depChangeset].node())
 
-                            # Pull the module in
-                            commands.pull(ui, moduleRepo, source=sourcePath)
-                            commands.update(ui, moduleRepo, moduleRepo[changeset].node())
+            try:
+                # Edit the module's reverse dependency file to point back at this repo
+                with open(folderPath + '/' + revFileName, 'a') as revDepFile:
+                    #note("Setting %s as a dependent of module %s\n" % (repo.root, newAliasName))
+                    revDepFile.write("%s\n" % repo.root)
+            except:
+                warn("Couldn't open reverse dependency file\n")
+                raise   
 
-                        # Edit the module's reverse dependency file to point back at this repo
-                        with open(folderPath + '/' + revFileName, 'a') as revDepFile:
-                            revDepFile.write("%s\n" % repo.root)   
+            mapFilePath = GetRepoMapDependencyFilePath(repo)
+            with open(mapFilePath, 'a') as mapFile:
+                # Update the mapFile
+                #note("Mapping %s as a dependency of %s\n" % (newAliasName, repo.root))
+                mapFile.write("%s = %s\n" % (dependencyAliases[depIndex], folderPath))
 
-                        # Update the mapFile
-                        mapFile.write("%s = %s\n" % (alias, folderPath))
-
-
-def FindAndReplaceChangesetInFile(filePath, sourcePath, changeset, newChangeset):    
+def FindAndReplaceChangesetInFile(filePath, sourcePath, changeset, newChangeset):
+    note("Searching %s to find repo from %s and replace %s with %s\n" % (filePath, sourcePath, changeset, newChangeset))    
     try:
         with open(filePath) as fileObject:
             lines = fileObject.readlines()
             for line in lines:
                 if sourcePath in line and changeset in line:
                     line = line.replace(changeset, newChangeset)
+                    note("Replaced changeset with %s\n" % (newChangeset))
                 fileObject.write(line)
     except:
-        print "Error!"
+        warn("Couldn't open file\n")
+        raise
 
-def UpdateExistingDepGroupRepo(ui, repo, repoClass):
+def FindAndRemoveReverseDependency(revFilePath, revDepRepo):
+    note("Searching %s to find and remove %s\n" % (revFilePath, revDepRepo))
+    try:
+        with open(revFilePath) as fileObject:
+            lines = fileObject.readlines()
+
+        with open(revFilePath, 'w') as fileObject:
+            fileObject.seek(0)
+            fileObject.truncate()
+            for line in lines:
+                if revDepRepo not in line:
+                    fileObject.write(line)
+                else:
+                    note("%s removed\n" % revDepRepo)
+    except:
+        warn("Couldn't open file\n")
+        raise
+
+def UpdateDependencyGroupRepo(ui, repo, repoClass):
+    note("Updating Dependency Group Repo at %s\n" % repo.root)
+
+    rootFilePath, modulePath = GetRootFileAndModuleDirectoryPaths(repo, repoClass)
+
+    # Make sure the necessary file and directories are created.  If not yet created,
+    # this is the first time the root repo has been updated (it's being cloned).
+    if repoClass == 'Root':
+        # If the module directory doesn't exist, create it
+        if not os.path.exists(modulePath):
+            os.makedirs(modulePath)
+
+        # If .hgdeproot doesn't exist, create it
+        open(rootFilePath, 'w').close()
+
+    moduleAliases, moduleSourcePaths, moduleChangesets = GetModuleList(rootFilePath)
+    
     if repoClass != 'Root':
-        rootFilePath = repo.root + '/../../' + rootFileName
-        moduleAliases, moduleSourcePaths, moduleChangesets = GetModuleList(rootFilePath)
 
         currentModuleAlias = repo.root.rsplit('/',1)[-1]
         currentModuleChangeset = GetChangeContextShortID(repo['.'])
-        currentModuleListIndex = moduleAliases.index(currentModuleAlias)
+        currentModuleListIndex = None
+        if currentModuleAlias in moduleAliases:
+            currentModuleListIndex = moduleAliases.index(currentModuleAlias)
 
-        # Determine if the new changeset is different (we're updating to a new revision).
-        #if currentModuleChangeset != moduleChangesets[currentModuleListIndex]:
-        
         # Get a list of this repo's dependents
-        revFilePath = repo.root + '/' + revFileName
+        revFilePath = GetRepoReverseDependencyFilePath(repo)
         revDepList = GetDependentsList(revFilePath)
 
+        # Update the .hgdep file for all of the repos that depend on this repo.
+        for revDepRepoPath in revDepList:
+            FindAndReplaceChangesetInFile(  '%s/%s' % (revDepRepoPath, depFileName), 
+                                            moduleSourcePaths[currentModuleListIndex],
+                                            moduleChangesets[currentModuleListIndex],
+                                            currentModuleChangeset)
+    
         # Update the .hgdeproot file
         FindAndReplaceChangesetInFile(  rootFilePath, 
                                         moduleSourcePaths[currentModuleListIndex],
                                         moduleChangesets[currentModuleListIndex],
                                         currentModuleChangeset)
 
-        # Update the .hgdep file for all of the repos that depend on this repo.
-        for revDepRepoPath in revDepList:
-            FindAndReplaceChangesetInFile(  revDepRepoPath + '/' + depFileName, 
-                                            moduleSourcePaths[currentModuleListIndex],
-                                            moduleChangesets[currentModuleListIndex],
-                                            currentModuleChangeset)
+    # Search all modules to see which WERE dependents of this repo
+    # Remove this repo from their reverse dependcy file
+    for alias in moduleAliases:
+        FindAndRemoveReverseDependency("%s/%s/%s" % (modulePath, alias, revFileName), repo.root)
 
+    # Delete the map file and let it be recreated.
+    mapFilePath = GetRepoMapDependencyFilePath(repo)
+    if os.path.isfile(mapFilePath):
+        os.remove(mapFilePath)
 
-            
-        """
-        # If a module already exists for the new repo, map all of the
-        # dependents of the current repo to the module representing the
-        # new repo.  ?Then delete the current repo?
-        existingModuleIndex = None
-        for index, changeset in enumerate(moduleChangesets):
-            if changeset == moduleInfo[1] and module[2] == newShortId:
-                newModuleInfo = module
-                break;
+    # Set up new dependencies for updated repo
+    AddDependency(ui, repo, repoClass)    
 
-        if newModuleInfo:
-            depFilePath = repo.root + '/' + depFileName
-            try:
-                depFile = open(depFilePath,'r+')
-                # For each dependent, find the mapping for this repo
-                # and update the changeset value
-                for dependentPath in dependentPaths:
-                    for line in depFile.readlines():
-                        aliasAndRepo = line.split('=',1)
-                        alias = aliasAndRepo[0].strip()
-                        repoSource = aliasAndRepo[1].strip()
-                        repoAndChangeset = repoSource.split(' ', 1)
-                        sourcePath = repoAndChangeset[0].strip()
-                        changeset = repoAndChangeset[1].strip()
-
-                depFile.close()
-            except IOError:
-                depFile.close()
-                util.Abort('Could not open dependency file for R/W')
-        """
-
-
-
-
-            # If a module does not exist for the new repo, update the current
-            # repo to the desired changeset, update the dependants' .hgdep files
-            # and the root's .hgdeproot file with the new changeset.
-            #if not newModuleInfo:
 
 # Every command must take ui and and repo as arguments.
 # opts is a dict where you can find other command line flags.
 # Define hooks -- note that the actual function name it irrelevant.
 def preupdatehook(ui, repo, **kwargs):
     try:
-        repoClass, repoNew = ClassifyRepo(ui, repo)
-        #if repoClass != 'Regular':
+        depFilePath = GetRepoDependencyFilePath(repo)
+        mapFilePath = GetRepoMapDependencyFilePath(repo) 
+        
+        # If this is a repo with .hgdep file and it does not yet
+        # have a .hgdepmap file, create it.
+        #if os.path.isfile(depFilePath):
+        #    if not os.path.isfile(mapFilePath):
+        #        open(mapFilePath, 'w').close()
     except:
+        warn("Error in Dependency Group Pre-update Hook\n")
         return
 
 def updatehook(ui, repo, **kwargs):
     try:
-        repoClass, repoNew = ClassifyRepo(ui, repo)
+        repoClass = ClassifyRepo(ui, repo)
         if repoClass != 'Regular':
-            if repoNew == True:
-                UpdateNewDepGroupRepo(ui, repo, repoClass)
-            else:
-                UpdateExistingDepGroupRepo(ui, repo, repoClass)
+            UpdateDependencyGroupRepo(ui, repo, repoClass)
     except:
+        warn("Error in Dependency Group Update Hook\n")
         return
         
 def changegrouphook(ui, repo, **kwargs):
     print("Changegroup hook triggered")
 
-def uisetup(ui):
+#def uisetup(ui):
     # When pre-<cmd> and post-<cmd> hooks are configured by means of
     # the ui.setconfig() function, you must use the ui object passed
     # to uisetup or extsetup.
-    ui.setconfig("hooks", "pre-update.myextension", preupdatehook)
+    #ui.setconfig("hooks", "pre-update.myextension", preupdatehook)
     
 def reposetup(ui, repo):
     # Repository-specific hooks can be configured here. These include