Move normpath() from catalyst.support to catalyst.util
authorAndrew Gaffney <agaffney@gentoo.org>
Sun, 11 Jan 2009 21:58:43 +0000 (15:58 -0600)
committerAndrew Gaffney <agaffney@gentoo.org>
Sun, 11 Jan 2009 21:58:43 +0000 (15:58 -0600)
13 files changed:
ChangeLog
modules/catalyst/support.py
modules/catalyst/target/embedded.py
modules/catalyst/target/generic_stage.py
modules/catalyst/target/grp.py
modules/catalyst/target/livecd_stage1.py
modules/catalyst/target/livecd_stage2.py
modules/catalyst/target/netboot.py
modules/catalyst/target/netboot2.py
modules/catalyst/target/snapshot.py
modules/catalyst/target/stage1.py
modules/catalyst/target/stage2.py
modules/catalyst/util.py

index 91cd8e0897bf857bc3f33aec3b86b762723b90ad..a695ae6a3ff106e755a0dc978d71d2b0e656abdd 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -2,6 +2,16 @@
 # Copyright 2002-2009 Gentoo Foundation; 2008-2009 Various authors (see AUTHORS)
 # Distributed under the GPL v2
 
+  11 Jan 2009; Andrew Gaffney <agaffney@gentoo.org>
+  modules/catalyst/support.py, modules/catalyst/target/embedded.py,
+  modules/catalyst/target/generic_stage.py, modules/catalyst/target/grp.py,
+  modules/catalyst/target/livecd_stage1.py,
+  modules/catalyst/target/livecd_stage2.py,
+  modules/catalyst/target/netboot.py, modules/catalyst/target/netboot2.py,
+  modules/catalyst/target/snapshot.py, modules/catalyst/target/stage1.py,
+  modules/catalyst/target/stage2.py, modules/catalyst/util.py:
+  Move normpath() from catalyst.support to catalyst.util
+
   11 Jan 2009; Andrew Gaffney <agaffney@gentoo.org>
   modules/catalyst/support.py, modules/catalyst/target/stage1.py,
   modules/catalyst/target/stage2.py, modules/catalyst/util.py:
index 47e257441f0a9a63c6a2648d23c72165d9bf0a75..091c0a9c534c227dd941f95b6d606af941287395 100644 (file)
@@ -632,15 +632,3 @@ def countdown(secs=5, doing="Starting"):
                        time.sleep(1)
                print
 
-def normpath(mypath):
-       TrailingSlash=False
-        if mypath[-1] == "/":
-           TrailingSlash=True
-        newpath = os.path.normpath(mypath)
-        if len(newpath) > 1:
-                if newpath[:2] == "//":
-                        newpath = newpath[1:]
-       if TrailingSlash:
-           newpath=newpath+'/'
-        return newpath
-
index ed15b5ada06351d1964ff5f359050b1bac18b425..5a3bc4bfa808e98ffb92dca43afd821fdc368a99 100644 (file)
@@ -9,10 +9,9 @@ It sounds real complicated but basically it runs
 ROOT=/tmp/submerge emerge --blahblah foo bar
 """
 
-import os,string,imp,types,shutil
 from catalyst.support import *
 from generic_stage import *
-from stat import *
+import catalyst.util
 
 class embedded_target(generic_stage_target):
 
@@ -36,11 +35,11 @@ class embedded_target(generic_stage_target):
                                        "unbind","remove","empty","clean","capture","clear_autoresume"]
 
        def set_stage_path(self):
-               self.settings["stage_path"]=normpath(self.settings["chroot_path"]+"/tmp/mergeroot")
+               self.settings["stage_path"]=catalyst.util.normpath(self.settings["chroot_path"]+"/tmp/mergeroot")
                print "embedded stage path is "+self.settings["stage_path"]
 
        def set_root_path(self):
-               self.settings["root_path"]=normpath("/tmp/mergeroot")
+               self.settings["root_path"]=catalyst.util.normpath("/tmp/mergeroot")
                print "embedded root path is "+self.settings["root_path"]
 
 __target_map = {"embedded":embedded_target}
index 2f5c97fd7aaf2994a4a018855f5402b1c79baa35..80469487f28dac39774f9d9674f598a6bc3a7f80 100644 (file)
@@ -256,23 +256,23 @@ class generic_stage_target(generic_target):
                if "pkgcache_path" in self.settings:
                        if type(self.settings["pkgcache_path"])!=types.StringType:
                                self.settings["pkgcache_path"]=\
-                                       normpath(string.join(self.settings["pkgcache_path"]))
+                                       catalyst.util.normpath(string.join(self.settings["pkgcache_path"]))
                else:
                        self.settings["pkgcache_path"]=\
-                               normpath(self.settings["storedir"]+"/packages/"+\
+                               catalyst.util.normpath(self.settings["storedir"]+"/packages/"+\
                                self.settings["target_subpath"]+"/")
 
        def set_kerncache_path(self):
                if "kerncache_path" in self.settings:
                        if type(self.settings["kerncache_path"])!=types.StringType:
                                self.settings["kerncache_path"]=\
-                                       normpath(string.join(self.settings["kerncache_path"]))
+                                       catalyst.util.normpath(string.join(self.settings["kerncache_path"]))
                else:
-                       self.settings["kerncache_path"]=normpath(self.settings["storedir"]+\
+                       self.settings["kerncache_path"]=catalyst.util.normpath(self.settings["storedir"]+\
                                "/kerncache/"+self.settings["target_subpath"]+"/")
 
        def set_target_path(self):
-               self.settings["target_path"]=normpath(self.settings["storedir"]+\
+               self.settings["target_path"]=catalyst.util.normpath(self.settings["storedir"]+\
                        "/builds/"+self.settings["target_subpath"]+".tar.bz2")
                if "AUTORESUME" in self.settings\
                        and os.path.exists(self.settings["autoresume_path"]+\
@@ -314,18 +314,18 @@ class generic_stage_target(generic_target):
        def set_cdtar(self):
                if self.settings["spec_prefix"]+"/cdtar" in self.settings:
                        self.settings["cdtar"]=\
-                               normpath(self.settings[self.settings["spec_prefix"]+"/cdtar"])
+                               catalyst.util.normpath(self.settings[self.settings["spec_prefix"]+"/cdtar"])
                        del self.settings[self.settings["spec_prefix"]+"/cdtar"]
 
        def set_iso(self):
                if self.settings["spec_prefix"]+"/iso" in self.settings:
                        if self.settings[self.settings["spec_prefix"]+"/iso"].startswith('/'):
                                self.settings["iso"]=\
-                                       normpath(self.settings[self.settings["spec_prefix"]+"/iso"])
+                                       catalyst.util.normpath(self.settings[self.settings["spec_prefix"]+"/iso"])
                        else:
                                # This automatically prepends the build dir to the ISO output path
                                # if it doesn't start with a /
-                               self.settings["iso"] = normpath(self.settings["storedir"] + \
+                               self.settings["iso"] = catalyst.util.normpath(self.settings["storedir"] + \
                                        "/builds/" + self.settings["rel_type"] + "/" + \
                                        self.settings[self.settings["spec_prefix"]+"/iso"])
                        del self.settings[self.settings["spec_prefix"]+"/iso"]
@@ -353,12 +353,12 @@ class generic_stage_target(generic_target):
 
        def set_source_path(self):
                if "SEEDCACHE" in self.settings\
-                       and os.path.isdir(normpath(self.settings["storedir"]+"/tmp/"+\
+                       and os.path.isdir(catalyst.util.normpath(self.settings["storedir"]+"/tmp/"+\
                                self.settings["source_subpath"]+"/")):
-                       self.settings["source_path"]=normpath(self.settings["storedir"]+\
+                       self.settings["source_path"]=catalyst.util.normpath(self.settings["storedir"]+\
                                "/tmp/"+self.settings["source_subpath"]+"/")
                else:
-                       self.settings["source_path"]=normpath(self.settings["storedir"]+\
+                       self.settings["source_path"]=catalyst.util.normpath(self.settings["storedir"]+\
                                "/builds/"+self.settings["source_subpath"]+".tar.bz2")
                        if os.path.isfile(self.settings["source_path"]):
                                # XXX: Is this even necessary if the previous check passes?
@@ -372,22 +372,22 @@ class generic_stage_target(generic_target):
                        print "\tIf this is not desired, remove this directory or turn off"
                        print "\tseedcache in the options of catalyst.conf the source path"
                        print "\twill then be "+\
-                               normpath(self.settings["storedir"]+"/builds/"+\
+                               catalyst.util.normpath(self.settings["storedir"]+"/builds/"+\
                                self.settings["source_subpath"]+".tar.bz2\n")
 
        def set_dest_path(self):
                if "root_path" in self.settings:
-                       self.settings["destpath"]=normpath(self.settings["chroot_path"]+\
+                       self.settings["destpath"]=catalyst.util.normpath(self.settings["chroot_path"]+\
                                self.settings["root_path"])
                else:
-                       self.settings["destpath"]=normpath(self.settings["chroot_path"])
+                       self.settings["destpath"]=catalyst.util.normpath(self.settings["chroot_path"])
 
        def set_cleanables(self):
                self.settings["cleanables"]=["/etc/resolv.conf","/var/tmp/*","/tmp/*",\
                        "/root/*","/usr/portage"]
 
        def set_snapshot_path(self):
-               self.settings["snapshot_path"]=normpath(self.settings["storedir"]+\
+               self.settings["snapshot_path"]=catalyst.util.normpath(self.settings["storedir"]+\
                        "/snapshots/portage-"+self.settings["snapshot"]+".tar.bz2")
 
                if os.path.exists(self.settings["snapshot_path"]):
@@ -398,7 +398,7 @@ class generic_stage_target(generic_target):
        def set_snapcache_path(self):
                if "SNAPCACHE" in self.settings:
                        self.settings["snapshot_cache_path"]=\
-                               normpath(self.settings["snapshot_cache"]+"/"+\
+                               catalyst.util.normpath(self.settings["snapshot_cache"]+"/"+\
                                self.settings["snapshot"]+"/")
                        self.snapcache_lock=\
                                catalyst.lock.LockDir(self.settings["snapshot_cache_path"])
@@ -409,12 +409,12 @@ class generic_stage_target(generic_target):
                NOTE: the trailing slash is very important!
                Things *will* break without it!
                """
-               self.settings["chroot_path"]=normpath(self.settings["storedir"]+\
+               self.settings["chroot_path"]=catalyst.util.normpath(self.settings["storedir"]+\
                        "/tmp/"+self.settings["target_subpath"]+"/")
                self.chroot_lock=catalyst.lock.LockDir(self.settings["chroot_path"])
 
        def set_autoresume_path(self):
-               self.settings["autoresume_path"]=normpath(self.settings["storedir"]+\
+               self.settings["autoresume_path"]=catalyst.util.normpath(self.settings["storedir"]+\
                        "/tmp/"+self.settings["rel_type"]+"/"+".autoresume-"+\
                        self.settings["target"]+"-"+self.settings["subarch"]+"-"+\
                        self.settings["version_stamp"]+"/")
@@ -424,7 +424,7 @@ class generic_stage_target(generic_target):
                        os.makedirs(self.settings["autoresume_path"],0755)
 
        def set_controller_file(self):
-               self.settings["controller_file"]=normpath(self.settings["sharedir"]+\
+               self.settings["controller_file"]=catalyst.util.normpath(self.settings["sharedir"]+\
                        "/targets/"+self.settings["target"]+"/"+self.settings["target"]+\
                        "-controller.sh")
 
@@ -461,7 +461,7 @@ class generic_stage_target(generic_target):
                                self.settings["use"].append("bindist")
 
        def set_stage_path(self):
-               self.settings["stage_path"]=normpath(self.settings["chroot_path"])
+               self.settings["stage_path"]=catalyst.util.normpath(self.settings["chroot_path"])
 
        def set_mounts(self):
                pass
@@ -740,7 +740,7 @@ class generic_stage_target(generic_target):
                                print "Valid snapshot cache, skipping unpack of portage tree..."
                                unpack=False
                else:
-                       destdir=normpath(self.settings["chroot_path"]+"/usr/portage")
+                       destdir=catalyst.util.normpath(self.settings["chroot_path"]+"/usr/portage")
                        cleanup_errmsg="Error removing existing snapshot directory."
                        cleanup_msg=\
                                "Cleaning up existing portage tree (This can take a long time)..."
index 4b9428b77df0e86299d7fe47c85a50975d21e76a..4689129822c6c5e672ae11a05a69b50e095dbb5d 100644 (file)
@@ -33,7 +33,7 @@ class grp_target(generic_stage_target):
                generic_stage_target.__init__(self,spec,addlargs)
 
        def set_target_path(self):
-               self.settings["target_path"]=normpath(self.settings["storedir"]+"/builds/"+self.settings["target_subpath"]+"/")
+               self.settings["target_path"]=catalyst.util.normpath(self.settings["storedir"]+"/builds/"+self.settings["target_subpath"]+"/")
                if "AUTORESUME" in self.settings \
                        and os.path.exists(self.settings["autoresume_path"]+"setup_target_path"):
                        print "Resume point detected, skipping target path setup operation..."
@@ -73,7 +73,7 @@ class grp_target(generic_stage_target):
        def generate_digests(self):
                for pkgset in self.settings["grp"]:
                        if self.settings["grp/"+pkgset+"/type"] == "pkgset":
-                               destdir=normpath(self.settings["target_path"]+"/"+pkgset+"/All")
+                               destdir=catalyst.util.normpath(self.settings["target_path"]+"/"+pkgset+"/All")
                                print "Digesting files in the pkgset....."
                                digests=glob.glob(destdir+'/*.DIGESTS')
                                for i in digests:
@@ -84,11 +84,11 @@ class grp_target(generic_stage_target):
                                #ignore files starting with '.' using list comprehension
                                files=[filename for filename in files if filename[0] != '.']
                                for i in files:
-                                       if os.path.isfile(normpath(destdir+"/"+i)):
-                                               self.gen_contents_file(normpath(destdir+"/"+i))
-                                               self.gen_digest_file(normpath(destdir+"/"+i))
+                                       if os.path.isfile(catalyst.util.normpath(destdir+"/"+i)):
+                                               self.gen_contents_file(catalyst.util.normpath(destdir+"/"+i))
+                                               self.gen_digest_file(catalyst.util.normpath(destdir+"/"+i))
                        else:
-                               destdir=normpath(self.settings["target_path"]+"/"+pkgset)
+                               destdir=catalyst.util.normpath(self.settings["target_path"]+"/"+pkgset)
                                print "Digesting files in the srcset....."
 
                                digests=glob.glob(destdir+'/*.DIGESTS')
@@ -100,9 +100,9 @@ class grp_target(generic_stage_target):
                                #ignore files starting with '.' using list comprehension
                                files=[filename for filename in files if filename[0] != '.']
                                for i in files:
-                                       if os.path.isfile(normpath(destdir+"/"+i)):
-                                               #self.gen_contents_file(normpath(destdir+"/"+i))
-                                               self.gen_digest_file(normpath(destdir+"/"+i))
+                                       if os.path.isfile(catalyst.util.normpath(destdir+"/"+i)):
+                                               #self.gen_contents_file(catalyst.util.normpath(destdir+"/"+i))
+                                               self.gen_digest_file(catalyst.util.normpath(destdir+"/"+i))
 
        def set_action_sequence(self):
            self.settings["action_sequence"]=["unpack","unpack_snapshot",\
index b41dbee557260e6d3819e0ec9abfbdf3a9e81198..e54657de5362c35b80a34729fd26ab45c314246c 100644 (file)
@@ -5,6 +5,7 @@ Builder class for LiveCD stage1.
 
 from catalyst.support import *
 from generic_stage import *
+import catalyst.util
 
 class livecd_stage1_target(generic_stage_target):
        def __init__(self,spec,addlargs):
@@ -20,7 +21,7 @@ class livecd_stage1_target(generic_stage_target):
                                        "bind","chroot_setup","setup_environment","build_packages",\
                                        "unbind", "clean","clear_autoresume"]
        def set_target_path(self):
-               self.settings["target_path"]=normpath(self.settings["storedir"]+"/builds/"+self.settings["target_subpath"])
+               self.settings["target_path"]=catalyst.util.normpath(self.settings["storedir"]+"/builds/"+self.settings["target_subpath"])
                if "AUTORESUME" in self.settings \
                        and os.path.exists(self.settings["autoresume_path"]+"setup_target_path"):
                                print "Resume point detected, skipping target path setup operation..."
@@ -60,7 +61,7 @@ class livecd_stage1_target(generic_stage_target):
        def set_pkgcache_path(self):
                if "pkgcache_path" in self.settings:
                        if type(self.settings["pkgcache_path"]) != types.StringType:
-                               self.settings["pkgcache_path"]=normpath(string.join(self.settings["pkgcache_path"]))
+                               self.settings["pkgcache_path"]=catalyst.util.normpath(string.join(self.settings["pkgcache_path"]))
                else:
                        generic_stage_target.set_pkgcache_path(self)
 
index d09cb623c376f20734f564ee6d663aba2c05c0e8..270b858eca79ca92c5f4b0acb1f1b8effd3ed0f1 100644 (file)
@@ -31,11 +31,11 @@ class livecd_stage2_target(generic_stage_target):
                file_locate(self.settings, ["cdtar","controller_file"])
 
        def set_source_path(self):
-               self.settings["source_path"]=normpath(self.settings["storedir"]+"/builds/"+self.settings["source_subpath"]+".tar.bz2")
+               self.settings["source_path"]=catalyst.util.normpath(self.settings["storedir"]+"/builds/"+self.settings["source_subpath"]+".tar.bz2")
                if os.path.isfile(self.settings["source_path"]):
                        self.settings["source_path_hash"]=generate_hash(self.settings["source_path"])
                else:
-                       self.settings["source_path"]=normpath(self.settings["storedir"]+"/tmp/"+self.settings["source_subpath"]+"/")
+                       self.settings["source_path"]=catalyst.util.normpath(self.settings["storedir"]+"/tmp/"+self.settings["source_subpath"]+"/")
                if not os.path.exists(self.settings["source_path"]):
                        raise CatalystError,"Source Path: "+self.settings["source_path"]+" does not exist."
 
@@ -43,7 +43,7 @@ class livecd_stage2_target(generic_stage_target):
            self.settings["spec_prefix"]="livecd"
 
        def set_target_path(self):
-               self.settings["target_path"]=normpath(self.settings["storedir"]+"/builds/"+self.settings["target_subpath"]+"/")
+               self.settings["target_path"]=catalyst.util.normpath(self.settings["storedir"]+"/builds/"+self.settings["target_subpath"]+"/")
                if "AUTORESUME" in self.settings \
                        and os.path.exists(self.settings["autoresume_path"]+"setup_target_path"):
                                print "Resume point detected, skipping target path setup operation..."
index bb0263725e708720c0f9e078fb5158dfe1be2aed..864ffe9931682fda1f1bca07e39608f4f9072653 100644 (file)
@@ -53,7 +53,7 @@ class netboot_target(generic_stage_target):
 
        def set_root_path(self):
                # ROOT= variable for emerges
-               self.settings["root_path"]=normpath("/tmp/image")
+               self.settings["root_path"]=catalyst.util.normpath("/tmp/image")
                print "netboot root path is "+self.settings["root_path"]
 
 #      def build_packages(self):
index f0827761082a22b31ceea5ff649d1f06f59c2802..db5edfe13a89cbf63c1a0ce9424e14a9a75cbe66 100644 (file)
@@ -38,10 +38,10 @@ class netboot2_target(generic_stage_target):
 
                generic_stage_target.__init__(self,spec,addlargs)
                self.set_build_kernel_vars()
-               self.settings["merge_path"]=normpath("/tmp/image/")
+               self.settings["merge_path"]=catalyst.util.normpath("/tmp/image/")
 
        def set_target_path(self):
-               self.settings["target_path"]=normpath(self.settings["storedir"]+"/builds/"+\
+               self.settings["target_path"]=catalyst.util.normpath(self.settings["storedir"]+"/builds/"+\
                        self.settings["target_subpath"]+"/")
                if "AUTORESUME" in self.settings \
                        and os.path.exists(self.settings["autoresume_path"]+"setup_target_path"):
index 5cc471654967742f02d8ca233d335dff46ba9ace..d46963c2a6ff10c3265026149ffd5e64cb6b6156 100644 (file)
@@ -6,6 +6,7 @@ Builder class for snapshots.
 import os
 from catalyst.support import *
 from generic_stage import *
+import catalyst.util
 
 class snapshot_target(generic_stage_target):
        def __init__(self,myspec,addlargs):
@@ -16,12 +17,12 @@ class snapshot_target(generic_stage_target):
                self.settings=myspec
                self.settings["target_subpath"]="portage"
                st=self.settings["storedir"]
-               self.settings["snapshot_path"]=normpath(st+"/snapshots/portage-"+self.settings["version_stamp"]\
+               self.settings["snapshot_path"]=catalyst.util.normpath(st+"/snapshots/portage-"+self.settings["version_stamp"]\
                        +".tar.bz2")
-               self.settings["tmp_path"]=normpath(st+"/tmp/"+self.settings["target_subpath"])
+               self.settings["tmp_path"]=catalyst.util.normpath(st+"/tmp/"+self.settings["target_subpath"])
 
        def setup(self):
-               x=normpath(self.settings["storedir"]+"/snapshots")
+               x=catalyst.util.normpath(self.settings["storedir"]+"/snapshots")
                if not os.path.exists(x):
                        os.makedirs(x)
 
index 369d02f0ebb0ef6d073457a182897c8a81e4da92..ac2b192c725e87c77869bdded7f80c6933566cb4 100644 (file)
@@ -14,12 +14,12 @@ class stage1_target(generic_stage_target):
                generic_stage_target.__init__(self,spec,addlargs)
 
        def set_stage_path(self):
-               self.settings["stage_path"]=normpath(self.settings["chroot_path"]+self.settings["root_path"])
+               self.settings["stage_path"]=catalyst.util.normpath(self.settings["chroot_path"]+self.settings["root_path"])
                print "stage1 stage path is "+self.settings["stage_path"]
 
        def set_root_path(self):
                # sets the root path, relative to 'chroot_path', of the stage1 root
-               self.settings["root_path"]=normpath("/tmp/stage1root")
+               self.settings["root_path"]=catalyst.util.normpath("/tmp/stage1root")
                print "stage1 root path is "+self.settings["root_path"]
 
        def set_cleanables(self):
index 0c38337bce0d281097265ccefdfd21cde3c524d5..90877847b4750982e898c48abcf2979b560fb016 100644 (file)
@@ -14,10 +14,10 @@ class stage2_target(generic_stage_target):
                generic_stage_target.__init__(self,spec,addlargs)
 
        def set_source_path(self):
-               if "SEEDCACHE" in self.settings and os.path.isdir(normpath(self.settings["storedir"]+"/tmp/"+self.settings["source_subpath"]+"/tmp/stage1root/")):
-                       self.settings["source_path"]=normpath(self.settings["storedir"]+"/tmp/"+self.settings["source_subpath"]+"/tmp/stage1root/")
+               if "SEEDCACHE" in self.settings and os.path.isdir(catalyst.util.normpath(self.settings["storedir"]+"/tmp/"+self.settings["source_subpath"]+"/tmp/stage1root/")):
+                       self.settings["source_path"]=catalyst.util.normpath(self.settings["storedir"]+"/tmp/"+self.settings["source_subpath"]+"/tmp/stage1root/")
                else:
-                       self.settings["source_path"]=normpath(self.settings["storedir"]+"/builds/"+self.settings["source_subpath"]+".tar.bz2")
+                       self.settings["source_path"]=catalyst.util.normpath(self.settings["storedir"]+"/builds/"+self.settings["source_subpath"]+".tar.bz2")
                        if os.path.isfile(self.settings["source_path"]):
                                if os.path.exists(self.settings["source_path"]):
                                # XXX: Is this even necessary if the previous check passes?
@@ -26,7 +26,7 @@ class stage2_target(generic_stage_target):
                print "Source path set to "+self.settings["source_path"]
                if os.path.isdir(self.settings["source_path"]):
                        print "\tIf this is not desired, remove this directory or turn of seedcache in the options of catalyst.conf"
-                       print "\tthe source path will then be "+normpath(self.settings["storedir"]+"/builds/"+self.settings["source_subpath"]+".tar.bz2\n")
+                       print "\tthe source path will then be "+catalyst.util.normpath(self.settings["storedir"]+"/builds/"+self.settings["source_subpath"]+".tar.bz2\n")
 
        # XXX: How do these override_foo() functions differ from the ones in
        # generic_stage_target and why aren't they in stage3_target?
index 815c23e8ddf5bbfe66cbdf735b05fdcdd90dbaa4..dd3eab373aaf24f09e39192e510d262cea5531a3 100644 (file)
@@ -2,7 +2,7 @@
 Collection of utility functions for catalyst
 """
 
-import sys, traceback, os
+import sys, traceback, os, os.path
 
 def capture_traceback():
        etype, value, tb = sys.exc_info()
@@ -65,3 +65,11 @@ def list_to_string(mylist):
        mypack = " ".join(mypack)
        return mypack
 
+def normpath(mypath):
+       newpath = os.path.normpath(mypath)
+       if mypath.endswith('/'):
+               newpath += '/'
+       if len(newpath) > 1 and newpath[:2] == '//':
+               newpath = newpath[1:]
+       return newpath
+