# HG changeset patch
# User John Schneiderman
# Date 1426011863 -3600
# Node ID 3a0242e260ab39264ef299d446054936cf30bd27
# Parent 5ef160e59286fbbf3b7bac421ac3c5c4326d960c
Ability to add a repository plug-in. IN: -
diff -r 5ef160e59286 -r 3a0242e260ab doc/ChangeLog
--- a/doc/ChangeLog Mon Mar 09 21:24:51 2015 +0100
+++ b/doc/ChangeLog Tue Mar 10 19:24:23 2015 +0100
@@ -18,6 +18,7 @@
*** along with this program. If not, see . ***
********************************************************************************
2015-00-00 John Schneiderman 0.4.0
+- Ability to add a plug-in to a managed repository.
- No longer dependant upon third-party general file locker for repositories.
- Manager functions use exceptions for error handling.
2014-08-21 John Schneiderman 0.3.0
diff -r 5ef160e59286 -r 3a0242e260ab doc/TODO
--- a/doc/TODO Mon Mar 09 21:24:51 2015 +0100
+++ b/doc/TODO Tue Mar 10 19:24:23 2015 +0100
@@ -27,7 +27,7 @@
*** ***
*** Feature Goals ***
*** ***
-- Allow plug-ins addition and removal from repositories.
+- Allow plug-ins removal from repositories.
- Installation tutorial.
- User tutorials.
- Manager functions should take both an output and error device instead of defaulting to std.
diff -r 5ef160e59286 -r 3a0242e260ab src/hwm.py
--- a/src/hwm.py Mon Mar 09 21:24:51 2015 +0100
+++ b/src/hwm.py Tue Mar 10 19:24:23 2015 +0100
@@ -97,7 +97,11 @@
parser = argparse.ArgumentParser(description=_app_info.DESCRIPTION)
parser.add_argument('-l', '--list', action='store_true', help='Outputs a list of all the managed repositories.')
- manGrp = parser.add_argument_group('Manage', 'Options that operate upon managed repositories.')
+ plgInGrp = parser.add_argument_group('Manage Plug-Ins', 'Options that operate upon managed repository\'s plug-ins.')
+ plgInGrp.add_argument('-e', '--enable-plugin', action='store', nargs=1, type=str, default=None, help='Enable a plug-in in a repository.')
+ plgInGrp.add_argument('-f', '--plugin-file', action='store', nargs='?', type=str, default=None, help='The path to the plug-in script.')
+
+ manGrp = parser.add_argument_group('Manage Repositories', 'Options that operate upon managed repositories.')
manGrp.add_argument('storage', action='store', nargs='?', help='The storage-name of the repository to perform an action upon.')
manGrp.add_argument('-a', '--action', action='store', nargs=1, type=str, choices=['c', 'create', 'm', 'modify', 'd', 'delete', 'r', 'register'], help='Performs an action upon a managed repository.')
manGrp.add_argument('-i', '--ignore', action='store', nargs='+', default=None, help='The groups to place in an ignore file.')
@@ -113,6 +117,8 @@
if args.list:
manager.list()
+ elif args.enable_plugin is not None:
+ manager.plugInEnable(repo, args.enable_plugin[0], args.plugin_file)
elif args.action is None:
print >>sys.stderr, "No actionable arguments supplied."
exit(1)
@@ -129,7 +135,7 @@
exit(1)
exit(0)
except (ValueError, RuntimeError) as error:
- print >>sys.stderr, "Issue Discovered: %s" % error
+ print >>sys.stderr, "Execution Failed: %s" % error
exit(2)
except Exception as error:
import traceback
diff -r 5ef160e59286 -r 3a0242e260ab src/manager.py
--- a/src/manager.py Mon Mar 09 21:24:51 2015 +0100
+++ b/src/manager.py Tue Mar 10 19:24:23 2015 +0100
@@ -26,6 +26,33 @@
settings = config.Manager()
+def plugInEnable(repository, plugInName, scriptFile):
+ """ Enables a plug-in to a managed repository.
+
+ @pre The repository must already exist.
+
+ @param[in] repository The targeted repository to add a plug-in to.
+ @param[in] plugInName The name of the plug-in to add.
+ @param[in] scriptFile The file path location of the plug-in script.
+
+ @post The managed repository has it's configuration file enabling the
+ supplied plug-in.
+
+ @throws ValueError When the repository storage name does not exist.
+ """
+ from manrepo import RepositoryPlugin
+
+ with RepositoryManagerLock():
+ print "\tEnable plug-in %s for %s" % (plugInName, repository.StorageName)
+ if not __doesRepositoryStorageNameExist(repository):
+ raise ValueError("The repository '%s' does not exist." % repository.StorageName)
+
+ print 'Creating plug-in information ...'
+ plugIn = RepositoryPlugin(plugInName, scriptFile)
+ repository.addPlugIn(plugIn)
+ __writeRepositoryDetails(repository)
+
+
def create(repository, ignoreGroups, skipCommon):
""" Creates a new repository under HgWeb.
@@ -450,7 +477,7 @@
import stat
import sys
- print "Saving display details ..."
+ print "Saving repository configuration details ..."
config = settings.RepositoryPath + os.sep + repo.StorageName + os.sep + '.hg' + os.sep + 'hgrc'
if os.path.exists(config):
diff -r 5ef160e59286 -r 3a0242e260ab src/manrepo.py
--- a/src/manrepo.py Mon Mar 09 21:24:51 2015 +0100
+++ b/src/manrepo.py Tue Mar 10 19:24:23 2015 +0100
@@ -37,6 +37,8 @@
__contact = None
# The Mercurial repository interface.
__repo = None
+ # The collection of plug-ins enabled for a repository.
+ __plugIns = []
@property
def StorageName(self):
@@ -73,6 +75,11 @@
""" Sets the contact point for the managed repository. """
self.__contact = value
+ @property
+ def PlugIns(self):
+ """ Gets the collection of enabled plug-ins for the managed repository. """
+ return self.__plugIns
+
def __init__(self, repoName=None):
""" Initialises the object with the values from a managed repository
@@ -89,6 +96,9 @@
self.__displayName = self.__repo.ui.config('web', 'name', default=None)
self.__description = self.__repo.ui.config('web', 'description', default=None)
self.__contact = self.__repo.ui.config('web', 'contact', default=None)
+ plugInList = self.__repo.ui.configitems('extensions')
+ for plugIn in plugInList:
+ self.__plugIns.append(RepositoryPlugin(plugIn[0], plugIn[1]))
except error.RepoError:
pass
@@ -113,27 +123,90 @@
import os
with open(settings.RepositoryPath + os.sep + self.__storageName + os.sep + '.hg' + os.sep + 'hgrc', 'w') as hgrc:
- hgrc.write('[web]\n')
+ hgrc.write('[extensions]\n')
+ for plugIn in self.PlugIns:
+ if plugIn.scriptFile is None:
+ hgrc.write(plugIn.name + ' =\n')
+ else:
+ hgrc.write(plugIn.name + ' = ' + plugIn.scriptFile + '\n')
- if self.__displayName is None:
- hgrc.write('name = ' + self.__storageName + '\n')
+ hgrc.write('\n[web]\n')
+ if self.DisplayName is None:
+ hgrc.write('name = ' + self.StorageName + '\n')
else:
- hgrc.write('name = ' + self.__displayName + '\n')
+ hgrc.write('name = ' + self.DisplayName + '\n')
+
+ if self.Description is not None:
+ hgrc.write('description = ' + self.Description + '\n')
+
+ if self.Contact is not None:
+ hgrc.write('contact = ' + self.Contact + '\n')
+ # Needed for when repositories are re-named.
+ self = Repository(self.StorageName)
- if self.__description is not None:
- hgrc.write('description = ' + self.__description + '\n')
+ def __str__(self):
+ """ Converts the object contents into a human-friendly string. """
+ repo = "%s\n\tDisplay: %s\n\tDescription: %s\n\tContact: %s" % (self.StorageName, self.DisplayName, self.Description, self.Contact)
+ if len(self.PlugIns) > 0:
+ repo = repo + "\n\tPlug-ins:"
+ for plugIn in self.PlugIns:
+ repo = repo + "\n\t\t%s" % plugIn
+ return repo
+
+ def addPlugIn(self, plugIn):
+ """ Adds a plug-in to enable in a repository.
+
+ @param[in] plugIn The plug-in that is to be enabled.
+
+ @post The object now has the supplied plug-in as being enabled.
- if self.__contact is not None:
- hgrc.write('contact = ' + self.__contact + '\n')
+ @throws ValueError When the supplied plug-in is already enabled.
+ """
+ if plugIn not in self.PlugIns:
+ self.__plugIns.append(plugIn)
+ else:
+ raise ValueError("The plug-in '%s' is already enabled." % plugIn.name)
+
+
+class RepositoryPlugin(object):
+ __name = None
+ __scriptFile = None
+
+ @property
+ def name(self):
+ return self.__name
+
+ @property
+ def scriptFile(self):
+ return self.__scriptFile
+
+ def __init__(self, name, scriptFile=None):
+ import os
- if self.__repo is None:
- from mercurial import ui, hg
- import os
+ self.__name = name
+ if (scriptFile is not None and len(scriptFile) > 0):
+ if os.path.exists(scriptFile):
+ self.__scriptFile = scriptFile
+ else:
+ raise ValueError("The plug-in file '%s' was not found." % scriptFile)
+
+ def __eq__(self, other):
+ """ Determines if two repository plug-ins are the same.
- self.__repo = hg.repository(ui.ui(), settings.RepositoryPath + os.sep + self.__storageName)
- self.__displayName = self.__repo.ui.config('web', 'name', default=None)
- self.__description = self.__repo.ui.config('web', 'description', default=None)
- self.__contact = self.__repo.ui.config('web', 'contact', default=None)
+ @param[in] other The plug-in on the right-hand-side of the
+ equality operator to compare against.
+
+ @return Gives true when both plug-ins represent the same one,
+ else-wise gives false.
+ """
+ return self.name == other.name
+
+ def __str__(self):
+ """ Converts the object contents into a human-friendly string. """
+ if self.scriptFile is None:
+ return self.name
+ else:
+ return "%s -> %s" % (self.name, self.scriptFile)
class ManagedCollection(object):
@@ -164,3 +237,11 @@
for name, path in parser.items('paths'):
self.__repositories.append(Repository(name))
+
+ def __str__(self):
+ """ Converts the object contents into a human-friendly string. """
+ collection = ""
+ for repository in self.Repositories:
+ collection = collection + str(repository) + '\n'
+ collection.rstrip('\n')
+ return collection