Mercurial > hgweb.cgi > hwm
changeset 3:23750425eabb
Split repository creation into individual functions. IN: -
author | John Schneiderman <JohnMS@CodeGNU.com> |
---|---|
date | Mon, 21 Jul 2014 22:53:06 -0500 |
parents | 3f42faf8f864 |
children | d25225017d5f |
files | doc/TODO src/hwm.py src/manager.py |
diffstat | 3 files changed, 130 insertions(+), 43 deletions(-) [+] |
line wrap: on
line diff
--- a/doc/TODO Mon Jul 21 20:59:06 2014 -0500 +++ b/doc/TODO Mon Jul 21 22:53:06 2014 -0500 @@ -37,3 +37,4 @@ - User tutorials. - Generate default ignore file using XML. - Actually parse the hgweb.config file to work with it. +- Manager functions should take both an output and error device instead of defaulting to std.
--- a/src/hwm.py Mon Jul 21 20:59:06 2014 -0500 +++ b/src/hwm.py Mon Jul 21 22:53:06 2014 -0500 @@ -29,12 +29,12 @@ IMPORTS """ import configuration as config -import argparse -import manager -import repository -def is_hgWeb_user(userName): +# Configuration values for HgWebManager. +settings = config.Manager() + +def is_hgWeb_user(): """Determines if the current running user is the expected HgWeb user. @return Gives true when the user is the expected HgWeb user, false @@ -43,15 +43,18 @@ import getpass # FIXME: This isn't a secure check as it is based upon the environmental variable. - if userName == getpass.getuser(): + if settings.HgUser == getpass.getuser(): return True else: return False def main(args): - settings = config.Manager() - if not is_hgWeb_user(settings.HgUser): + import argparse + import repository + import manager + + if not is_hgWeb_user(): print >>sys.stderr, "Must execute as the Mercurial Web manager." exit(1) @@ -65,7 +68,7 @@ repo = repository.extract_values(args) if args.create: - if manager.create(settings, repo): + if manager.create(repo): print "Success creating repository %s." % repo.StorageName else: print "Failure creating repository %s." % repo.StorageName
--- a/src/manager.py Mon Jul 21 20:59:06 2014 -0500 +++ b/src/manager.py Mon Jul 21 22:53:06 2014 -0500 @@ -24,65 +24,148 @@ IMPORTS """ import repository +from hwm import settings -def create(settings, repository): +def create(repository): + """ Creates a new repository under HgWeb. + @todo Check the existence of the requested repository. + + @pre The repository to create cannot already exist. + + @param[in] repository The targeted repository to create. + + @post The file system now contains a new directory in the repository path + that is the newly generated repository. The new repository is registered + in HgWeb to display and is secured to prevent accidental modification. + + @return When the creation is successful gives true, else-wise false. + """ + import sys + + print "Generating repository: " + repository.StorageName + # Create the requested repository. + status = __generateRepository(repository) + if 0 == status: + print "Created repository directory." + else: + print >>sys.stderr, "Failed to create repository directory.", status + return False + + # Fill out the details of about the repository. + if __writeRepositoryDetails(repository): + print "Wrote repository details." + else: + print >>sys.stderr, "Failed to write repository details." + return False + + # Add the new repository to the web register. + if __registerRepository(repository): + return True + else: + return False + +def __generateRepository(repo): + """ Initialises a new Mercurial repository. + + @pre The requested repository to create cannot already exist. + + @param[in] repo The targeted repository for which to create. + + @post Upon any error the standard error buffer contains an error message. + + @return When the process is successful gives true, else-wise false. + """ import subprocess import sys import os - import stat - import shutil - print "Generating repository:" + repository.StorageName - repoBase = settings.RepositoryPath + os.sep + repository.StorageName - config = repoBase + os.sep + ".hg" + os.sep + "hgrc" - # Create the requested repository. try: - repoCreateStatus = subprocess.call([settings.HgCommand, "init", repoBase]) - - if 0 == repoCreateStatus: - print "Created repository directories." - else: - print >>sys.stderr, "Failed to create repository directories.", repoCreateStatus - return False + return subprocess.call([settings.HgCommand, "init", settings.RepositoryPath + os.sep + repo.StorageName]) except OSError as e: print >>sys.stderr, "Initialisation error({0}): {1}".format(e.errno, e.strerror) return False + return True - # Fill out the details of about the repository. +def __writeRepositoryDetails(repo): + """ Writes the details of a repository to the repository configuration file. + + @param[in] repo The targeted repository for which to write the + configuration details. + + @post The HgWeb configuration file contains the new repository details and + is returned to a read-only state. + + @return When the process is successful gives true, else-wise false. + """ + import os + import stat + import sys + + config = settings.RepositoryPath + os.sep + repo.StorageName + os.sep + ".hg" + os.sep + "hgrc" with open(config, "w") as hgrc: hgrc.write("[web]\n") - if repository.DisplayName is None: - hgrc.write("name = " + repository.StorageName + '\n') + if repo.DisplayName is None: + hgrc.write("name = " + repo.StorageName + '\n') else: - hgrc.write("name = " + repository.DisplayName + '\n') - if repository.Description is not None: - hgrc.write("description = " + repository.Description + '\n') - if repository.Contact is not None: - hgrc.write("contact = " + repository.Contact + '\n') - print "Wrote repository details." + hgrc.write("name = " + repo.DisplayName + '\n') + if repo.Description is not None: + hgrc.write("description = " + repo.Description + '\n') + if repo.Contact is not None: + hgrc.write("contact = " + repo.Contact + '\n') # Ensure the repository details isn't accidentally modified. hgrcMode = os.stat(config)[stat.ST_MODE] os.chmod(config, hgrcMode & ~stat.S_IWUSR & ~stat.S_IWGRP & ~stat.S_IWOTH) - print "Write protected repository details." - # Ensure the repository store isn't accidentally deleted, moved, or blocked in Windows. + # Ensure the repository isn't accidentally deleted, moved, or blocked. if "win32" == sys.platform: - repoStoreStatus = subprocess.call(["attrib.exe", "+H +I +S " + repoBase + os.sep + ".hg"]) - if 0 == repoStoreStatus: - print "Secured repository store." - else: - print >>sys.stderr, "Failed to secure repository store.", repoStoreStatus - exit(repoStoreStatus) + status = __guardWindowsRepository(repository) + if 0 != status: + exit(status) + return True + +def __guardWindowsRepository(repo): + """ Guards the supplied repository when on a Windows system. + + @param[in] repo The targeted repository for which to secure. + + @return The exit status value from securing the repository. The value will + be zero upon success, all other values indicate failure. + """ + import subprocess + import os + import sys - # Add the new repository to the web register. + status = subprocess.call(["attrib.exe", "+H +I +S " + settings.RepositoryPath + os.sep + repo.StorageName + os.sep + ".hg"]) + if 0 == status: + print "Secured repository store." + else: + print >>sys.stderr, "Failed to secure repository store.", status + return status + +def __registerRepository(repo): + """ Registers the repository with HgWeb. + + @param[in] repo The targeted repository for which to register in + HgWeb. + + @post The HgWeb configuration file contains the new repository details and + is returned to a read-only state. Upon any error the standard error + buffer contains an error message. + + @return When the process is successful gives true, else-wise false. + """ + import os + import sys + import shutil + try: with open(settings.HgWebPath + os.sep + "hgweb.config", "a") as hgweb: - hgweb.write('\n' + repository.StorageName + " = " + repoBase) + hgweb.write('\n' + repo.StorageName + " = " + settings.RepositoryPath + os.sep + repo.StorageName) + return True except IOError as e: print >>sys.stderr, "Web Configuration error({0}): {1}".format(e.errno, e.strerror) os.chmod(config, stat.S_IWRITE) - shutil.rmtree(repoBase) + shutil.rmtree(settings.RepositoryPath + os.sep + repo.StorageName) return False - return True