berlios / bcd /

#!/usr/bin/env python
'''Tkinter replacement to cdargs utility'''

# =====================================================
# Copyright (c) Miki Tebeka <> 
# This file is under the GNU Public License (GPL), see
# for more details
# =====================================================

__author__ = "Miki Tebeka <>"
__version__ = "0.5.0"

from user import home
from os.path import join, isfile, expandvars, isdir
from os import environ, system
from sys import platform, stderr
from ConfigParser import ConfigParser, Error as ConfigParserError


def rc_filename():
    if "BCDRC" in environ:
        return environ["BCDRC"]

    if platform == "win32":
        prefix = "_"
        prefix = "."
    return join(home, prefix + "bcdrc")

def load_rc(filename):
    aliases = {}
    for line in open(filename):
        line = line.strip()
        if (not line) or line[0] == "#":
        name, path = line.split("=", 1)
        name = name.strip()
        path = path.strip()

        aliases[name] = path

    return aliases

def print_path(path):
    path = expandvars(path)
    if platform == "win32":
        print "@echo off"
        print "cd /d %s" % path
        print path

def check(aliases):
    ok = 1
    items = aliases.items()
    for alias, path in items:
        print "%s: %s" % (alias, path),
        path = resolve(path)
        if not isdir(path):
            print "[ERROR]"
            ok = 0
            print "[OK]"

    return ok

def main(argv = None):

    if argv is None:
        import sys
        argv = sys.argv

    from optparse import OptionParser

    # Command line parsing
    parser = OptionParser("usage: %prog [options] [ALIAS]", 
            version="bcd " + __version__)
    parser.add_option("-c", help="compelte alias", dest="complete", default=0,
    parser.add_option("--check", help="check aliases", dest="check", default=0,

    opts, args = parser.parse_args()
    if (not opts.complete) and (not opts.check) and \
        (len(args) not in (0, 1)):
        parser.error("wrong number of arguments") # Will exit

    rcfile = rc_filename()

    if not isfile(rcfile):
        raise SystemExit("can't find initialization file %s" % rcfile)

        # Initial load of rc file
        aliases = load_rc(rcfile)
    except (IOError, ConfigParserError, ValueError), e:
        raise SystemExit("bcd: %s: error: %s" % (rcfile, e))

    if opts.check:
        retval = 0
        if not check(aliases):
            retval = 1
        raise SystemExit(retval)

    # Print all aliases starting with argument
    if opts.complete:
        if args:
            prefix = args[1]
            prefix = "" # string.startswith("") is always true
        for alias in aliases:
            if alias.startswith(prefix):
                print alias
        raise SystemExit

    # Try to find given alias
    if args:
        path = aliases.get(args[0], None)
        if path:
            raise SystemExit

    # Not found or no arguments, show all options
    # We print to stderr so it won't be caught but the wrapping function
    max_alias_length = max([len(a[0]) for a in aliases])
    padding = 5
    for alias, path in sorted(aliases.items()):
        line = "-" * (max_alias_length + padding - len(alias))
        print >> stderr, "%s %s %s" % (alias, line, path)

    if args: # Didn't find
        raise SystemExit("error: can't find %s" % args[0])

if __name__ == "__main__":