summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSérgio Almeida <mephx@thedude.(none)>2009-06-17 18:45:31 +0100
committerSérgio Almeida <mephx@thedude.(none)>2009-06-17 18:45:31 +0100
commit5e561c1bb476977119fb947a4e21fe6dd4e3c314 (patch)
treeedc9261465523b884f869145aa97a0b7dd9ccd2b
downloaduselect-5e561c1bb476977119fb947a4e21fe6dd4e3c314.tar.gz
uselect-5e561c1bb476977119fb947a4e21fe6dd4e3c314.tar.bz2
uselect-5e561c1bb476977119fb947a4e21fe6dd4e3c314.zip
Initial Universal Select Tool Commit
-rw-r--r--install.sh11
-rw-r--r--modules/env.uselect325
-rw-r--r--modules/gcc.uselect41
-rw-r--r--modules/kernel.uselect24
-rw-r--r--modules/one.uselect44
-rw-r--r--modules/python.uselect21
-rw-r--r--uio.py253
-rw-r--r--umodule.py274
-rwxr-xr-xuselect.py99
9 files changed, 1092 insertions, 0 deletions
diff --git a/install.sh b/install.sh
new file mode 100644
index 0000000..326f761
--- /dev/null
+++ b/install.sh
@@ -0,0 +1,11 @@
+#!/bin/bash
+#
+# Uselect Temporary installer
+#
+
+PWD=`pwd`
+
+rm -f /usr/bin/uselect
+rm -f /usr/share/uselect
+ln -s $PWD/uselect.py /usr/bin/uselect
+ln -s $PWD /usr/share/uselect
diff --git a/modules/env.uselect b/modules/env.uselect
new file mode 100644
index 0000000..effed56
--- /dev/null
+++ b/modules/env.uselect
@@ -0,0 +1,325 @@
+# Copyright 1999-2009 Gentoo Foundation
+# Distributed under the terms of the GNU General Public License v2
+# env.uselect mephx.x@gmail.com
+
+module env {
+ description "Manage environment variables set in /etc/env.d/"
+ version "0.1"
+ author "mephx.x@gmail.com"
+} env
+
+
+user action update
+ description "Collect environment variables from all scripts in /etc/env.d/"
+ parameters "<makelinks> <noldconfig>"
+ options {
+ "makelinks : Specify \"makelinks\" to force updating of links"
+ "noldconfig : Do not alter the ld.so cache or configuration."
+ }
+ type runnable
+
+ file env-update.bash {
+ #!/bin/bash
+ # Classes of env-vars
+
+ source /usr/share/eselect/libs/tests.bash
+ source /usr/share/eselect/libs/core.bash
+ source /usr/share/eselect/libs/path-manipulation.bash
+
+ source /usr/share/eselect/libs/config.bash
+ source /usr/share/eselect/libs/multilib.bash
+
+ SPACE_CLASS="CONFIG_PROTECT
+ CONFIG_PROTECT_MASK"
+ PATH_CLASS="ADA_INCLUDE_PATH
+ ADA_OBJECT_PATH
+ CLASSPATH
+ INFODIR
+ INFOPATH
+ KDEDIRS
+ LDPATH
+ MANPATH
+ PATH
+ PKG_CONFIG_PATH
+ PRELINK_PATH
+ PRELINK_PATH_MASK
+ PYTHONPATH
+ ROOTPATH"
+
+ # Recognized file formats:
+ MIME_WHITELIST="text/plain text/x-makefile"
+
+ # Configuration files
+ ENVPROFILE="${ROOT}/etc/profile.env"
+ LDCONFIG="${ROOT}/etc/ld.so.conf"
+ PRELINK="${ROOT}/etc/prelink.conf"
+ LDMTIMEDB="${ROOT}/var/lib/eselect/env/ld-mtimedb"
+
+ # Keep all stored LDPATHS
+ ESELECT_LDPATH=( )
+
+ # is_envd_file()
+ # Return successfuly when file can be sourced.
+ is_envfile() {
+ local mime envfile=${1}
+
+ # Make sure it is a file and no backup file
+ [[ -f ${envfile} ]] || return 1
+ [[ -n ${envfile##*~} ]] || return 1
+ [[ ${envfile##*.} != bak ]] || return 1
+
+ mime=$(POSIXLY_CORRECT=1 file -i ${envfile} \
+ | cut -d ' ' -f 2 | sed -e 's/;$//')
+ if ! has ${mime} ${MIME_WHITELIST} ; then
+ echo "Skipping non-text file ${envfile}."
+ return 1
+ fi
+
+ return 0
+ }
+
+ # update_envvar_classes()
+ # Update the contents of *_CLASS based on env,d files.
+ update_envvar_classes() {
+ local -a envfiles
+ local value
+ envfiles=( ${ROOT}/etc/env.d/* )
+
+ for envfile in ${envfiles[@]} ; do
+ is_envfile ${envfile} || continue
+
+ value=$(load_config ${envfile} COLON_SEPARATED)
+ for x in ${value} ; do
+ has ${x} ${PATH_CLASS} && continue
+ PATH_CLASS="${PATH_CLASS} ${x}"
+ done
+
+ value=$(load_config ${envfile} SPACE_SEPARATED)
+ for x in ${value} ; do
+ has ${x} ${SPACE_CLASS} && continue
+ SPACE_CLASS="${SPACE_CLASS} ${x}"
+ done
+ done
+ }
+
+ # create_profile_env()
+ # Create profile.env file
+ create_profile_env() {
+ local -a envfiles
+ local vars store items tmpprofile
+ envfiles=( ${ROOT}/etc/env.d/* )
+
+ # Blank the file first!
+ tmpprofile="$(mktemp ${ROOT}/tmp/profile.XXXXXX)"
+ [[ $? = 0 ]] || die "Couldn't create temporary file!"
+
+ # Gather ye classes while ye may!
+ update_envvar_classes
+
+ # Parse all files in env.d
+ for envfile in ${envfiles[@]} ; do
+ is_envfile ${envfile} || continue
+
+ # Which vars are to be loaded?
+ # TODO: Change to bash magic?
+ vars=$(sed \
+ -e '/^#/d' -e '/^\s*$/d' -e '/^.*=/s/^\([^=]*\)=.*/\1/' \
+ ${envfile})
+ [[ -z ${vars} ]] && continue
+ for var in ${vars} ; do
+ # Colon separated?...
+ if has ${var} ${PATH_CLASS} ; then
+ store=$(load_config ${tmpprofile} ${var})
+ if [[ -z ${store} ]] ; then
+ store=$(load_config ${envfile} ${var})
+ else
+ items="$(load_config ${envfile} ${var})"
+ items=( ${items//:/ } )
+ for item in ${items[@]} ; do
+ has ${item} ${store//:/ } && continue
+ store="${store}:${item}"
+ done
+ fi
+ store_config ${tmpprofile} ${var} "${store#:}"
+ continue
+ fi
+ # Space separated!...
+ if has ${var} ${SPACE_CLASS} ; then
+ store=( $(load_config ${tmpprofile} ${var}) )
+ if [[ -z ${store[@]} ]] ; then
+ store=( $(load_config ${envfile} ${var}) )
+ else
+ items=( $(load_config ${envfile} ${var}) )
+ for item in ${items[@]} ; do
+ has ${item} ${store[@]} && continue
+ store=( ${store[@]} ${item} )
+ done
+ fi
+ store_config ${tmpprofile} ${var} "${store[@]}"
+ continue
+ fi
+ # Ok, just a non-cummultative var.
+ store_config \
+ ${tmpprofile} \
+ ${var} \
+ "$(load_config ${envfile} ${var})"
+ done
+
+ has LDPATH ${vars} || continue
+ # Store LDPATH for later processing
+ items=$(load_config ${envfile} LDPATH)
+ items=( ${items//:/ } )
+ for item in ${items[@]} ; do
+ has ${item} ${LDPATH[@]} && continue
+ ESELECT_LDPATH=( ${ESELECT_LDPATH[@]} ${item} )
+ done
+ done
+
+ # Move new file onto old one
+ ENVPROFILE=$(canonicalise ${ENVPROFILE})
+ chmod a+r ${tmpprofile}
+ mv ${tmpprofile} ${ENVPROFILE} \
+ || die "Couldn't move ${tmpprofile} to ${ENVPROFILE}!\n
+ Original profile.env remains unchanged."
+ }
+
+ # create_ld_so_conf()
+ # Create ld.so.conf file based upon gathered LDPATHs
+ create_ld_so_conf() {
+ [[ -z ${ESELECT_LDPATH[@]} ]] && die -q 'No LDPATHs found in ${ROOT}/etc/env.d/*'
+
+ local str
+ str="# ld.so.conf autogenerated by eselect\n"
+ str="${str}# Make all changes to /etc/env.d files\n"
+ for x in ${ESELECT_LDPATH[@]} ; do
+ str="${str}${x}\n"
+ done
+ echo -e "${str}" > $(canonicalise ${LDCONFIG})
+ }
+
+ # create_prelink_conf()
+ # Create prelink.conf file based upon existing profile.env
+ create_prelink_conf() {
+ [[ -z ${ESELECT_LDPATH[@]} ]] && die -q 'No LDPATHs found in ${ROOT}/etc/env.d/*'
+ local str
+ str="# prelink.conf autogenerated by eselect\n"
+ str="${str}# Make all changes to /etc/env.d files\n"
+ # Add default items
+ for x in /bin /sbin /usr/bin /usr/sbin ; do
+ str="${str}-l ${x}\n"
+ done
+ for x in $(list_libdirs) ; do
+ [[ -e ${ROOT}/${x} ]] && str="${str}-l /${x}\n"
+ [[ -e ${ROOT}/usr/${x} ]] && str="${str}-l /usr/${x}\n"
+ done
+ prelink_mask=$(load_config ${ENVPROFILE} PRELINK_PATH_MASK)
+ prelink_mask=( ${prelink_mask//:/ } )
+ prelink="$(load_config ${ENVPROFILE} PATH)"
+ prelink="${prelink} $(load_config ${ENVPROFILE} PRELINK_PATH)"
+ prelink=( ${prelink//:/ } ${ESELECT_LDPATH[@]} )
+ for x in ${prelink[@]} ; do
+ has ${x} ${prelink_mask} && continue
+ [[ -z ${x##*/} ]] || x="${x}/"
+ str="${str}-h ${x}\n"
+ done
+ for x in ${prelink_mask[@]} ; do
+ str="${str}-b ${x}\n"
+ done
+ echo -e "${str}" > $(canonicalise ${PRELINK})
+ }
+
+ # need_links()
+ # Returns true if any item of ${LDPATH} has been modified.
+ need_links() {
+ local ret=1
+ for x in ${ESELECT_LDPATH[@]} ; do
+ y=${x//\//_}
+ y=${y//-/_}
+ y=${y//./_}
+ y=${y//+/_}
+ oldmtime=$(load_config ${LDMTIMEDB} "mtime${y}")
+ newmtime=$(stat -c %Y ${x} 2> /dev/null)
+ if [[ ${oldmtime} != ${newmtime} ]] ; then
+ ret=0
+ store_config ${LDMTIMEDB} "mtime${y}" ${newmtime}
+ fi
+ done
+ return ${ret}
+ }
+
+ # update_ldcache()
+ # Update ld.so.cache using ldconfig
+ update_ldcache() {
+ case $(uname -s) in
+ FreeBSD | DragonFly)
+ echo "Regenerating ${ROOT}/var/run/ld-elf.so.hints..."
+ (
+ cd /
+ ldconfig -elf -i -f "${ROOT:-/}var/run/ld-elf.so.hints" \
+ "${ROOT:-/}etc/ld.so.conf"
+ )
+ ;;
+ *)
+ echo "Regenerating ${ROOT}/etc/ld.so.cache..."
+ (
+ cd /
+ ldconfig ${1} -r ${ROOT:-/}
+ )
+ ;;
+ esac
+ }
+
+ ### update action
+
+
+
+
+ do_update() {
+ local makelinks ldconfig=1
+ while [[ ${#@} -gt 0 ]] ; do
+ case ${1} in
+ makelinks)
+ makelinks="-X"
+ ;;
+ noldconfig)
+ ldconfig=0
+ ;;
+ *)
+ die -q "Unknown option '${1}'"
+ ;;
+ esac
+ shift
+ done
+
+ if [[ -e ${ROOT}/etc/profile.env ]] ; then
+ [[ -w ${ROOT}/etc/profile.env ]] \
+ || die -q "You need to be root!"
+ else
+ touch ${ROOT}/etc/profile.env
+ fi
+
+ # Create configuration files
+ create_profile_env
+ if [[ ${ldconfig} == 1 ]] ; then
+ create_ld_so_conf
+ [[ -e ${ROOT}/usr/sbin/prelink ]] && create_prelink_conf
+ need_links && makelinks="-X"
+ update_ldcache ${makelinks}
+ fi
+
+ # fix up ${ENVPROFILE}
+ cp ${ENVPROFILE} ${ENVPROFILE/.env/.csh}
+ sed -i \
+ -e "s/^\(.*\)=\"\(.*\)\"/export \1='\2'/" \
+ $(canonicalise ${ENVPROFILE})
+ sed -i \
+ -e "s/^\(.*\)=\"\(.*\)\"/setenv \1 '\2'/" \
+ $(canonicalise ${ENVPROFILE/.env/.csh})
+ }
+
+ do_update $@
+
+ } env-update.bash
+} update
+
+# vim: ft=eselect
diff --git a/modules/gcc.uselect b/modules/gcc.uselect
new file mode 100644
index 0000000..10a1fad
--- /dev/null
+++ b/modules/gcc.uselect
@@ -0,0 +1,41 @@
+module gcc{
+ description "GCC Version Switcher"
+ version "0.1"
+ author "mephx.x@gmail.com"
+} gcc
+
+system action profile {
+ description "Change GCC's /usr/bin/gcc Version"
+ type runnable
+ parameters "<target>"
+ usage "<target> Target GCC profile."
+ file moo.bash {
+ #!/bin/bash
+ do_moo() {
+ if [ -z $1 ]
+ then
+ gcc-config -l
+ else
+ gcc-config $@
+ fi
+ }
+ do_moo $@
+ } moo.bash
+} profile
+
+system action bin {
+ description "Print path where binaries of the given/current profile are located."
+ type runnable
+ file moo.bash {
+ #!/bin/bash
+ do_moo() {
+ if [ -z $1 ]
+ then
+ gcc-config -B
+ else
+ gcc-config -B
+ fi
+ }
+ do_moo $@
+ } moo.bash
+} bin
diff --git a/modules/kernel.uselect b/modules/kernel.uselect
new file mode 100644
index 0000000..646730a
--- /dev/null
+++ b/modules/kernel.uselect
@@ -0,0 +1,24 @@
+# Copyright 1999-2009 Gentoo Foundation
+# Distributed under the terms of the GNU General Public License v2
+# kernel.uselect mephx.x@gmail.com
+
+module kernel {
+ description "Kernel Switcher"
+ version "0.1"
+ author "mephx.x@gmail.com"
+} kernel
+
+system action src {
+ description "Change current kernel source target"
+ type sym
+ sym linux /usr/src/linux /usr/src/ (.*)-(.*$) *
+} src
+
+system action boot {
+ description "Change current kernel boot target"
+ type sym
+ sym vmlinuz /boot/vmlinuz /boot/ vmlinuz-(.*$) *
+} boot
+
+
+
diff --git a/modules/one.uselect b/modules/one.uselect
new file mode 100644
index 0000000..91e3709
--- /dev/null
+++ b/modules/one.uselect
@@ -0,0 +1,44 @@
+# Copyright 1999-2009 Gentoo Foundation
+# Distributed under the terms of the GNU General Public License v2
+# one.uselect mephx.x@gmail.com
+
+module one {
+ description "Example Module description"
+ version "0.2"
+ author "mephx.x@gmail.com"
+} one
+
+user action moo {
+ description "Example Module will moo for any user"
+ parameters "<integer>"
+ usage "<integer> - number of moos"
+ type runnable
+ file moo.bash {
+ #!/bin/bash
+ do_moo() {
+ if [ -z $1 ]
+ then
+ # print options
+ echo "1 - moo one time"
+ echo "2 - moo two times"
+ echo "3 - moo three times"
+ echo "x - moo x times"
+ else
+ for((i=0;$i<$1;i=$(($i+1))));do
+ echo moo
+ done
+ fi
+ }
+ do_moo $@
+ } moo.bash
+} moo
+
+system action foo {
+ description "Example Simple symlinking Action"
+ usage "moo <option>"
+ type sym
+ sym /usr/moo /usr/share/ moo-(\w+) /bin/moo
+} foo
+
+
+
diff --git a/modules/python.uselect b/modules/python.uselect
new file mode 100644
index 0000000..79df588
--- /dev/null
+++ b/modules/python.uselect
@@ -0,0 +1,21 @@
+# Copyright 1999-2009 Gentoo Foundation
+# Distributed under the terms of the GNU General Public License v2
+# python.uselect mephx.x@gmail.com
+
+module python {
+ description "Python Version Switcher"
+ version "0.1"
+ author "mephx.x@gmail.com"
+} python
+
+user action bin {
+ description "Change Python's Version"
+ type sym
+ sym python /usr/bin/python /usr/bin/ python([0-9]+\.[0-9]+$) *
+} bin
+
+system action config {
+ description "Change Python's /usr/bin/python-config Version"
+ type sym
+ sym python /usr/bin/python-config /usr/bin/ python([0-9]+\.[0-9]+)-config($) *
+} config
diff --git a/uio.py b/uio.py
new file mode 100644
index 0000000..c2aa423
--- /dev/null
+++ b/uio.py
@@ -0,0 +1,253 @@
+#!/usr/bin/env python
+# Copyright 1999-2009 Gentoo Foundation
+# Distributed under the terms of the GNU General Public License v2
+# Universal Select Tool
+# Uselect Input/Output Module
+# uio.py mephx.x@gmail.com
+
+import os
+import pwd
+import stat
+
+# Aligning
+space = ' '
+right = '\t'
+
+# Globals
+bold = lime = red = reset = yellow = notice = ''
+error = warning = bullet = ok = highlight = ''
+
+verbose = False
+
+class FileSystem:
+ """ FileSystem Class """
+ def __init__(self):
+ """ FileSystem Contructor """
+ self.home = os.getenv('HOME')
+ self.uid = pwd.getpwuid(os.getuid())[0]
+ self.environment = self.home + '/.uselect/'
+ if not os.path.exists(self.environment):
+ os.mkdir(self.environment)
+ self.environment += 'bin/'
+ if not os.path.exists(self.environment):
+ os.mkdir(self.environment)
+
+ def read_file(self, path):
+ """ Reads a File and returns lines[] """
+ file = open(path,'r')
+ lines = file.readlines()
+ file.close
+ return lines
+
+ def write_file(self, path ,lines):
+ """ Writes "lines[]" in File "path" """
+ if os.path.exists(path):
+ raise Exception("File in " + path + " already Exists!")
+ return
+ file = open(path,'w')
+ for line in lines:
+ file.writelines(line + '\n')
+ file.close
+ return lines
+
+ def execute_cmd(self, cmd, args):
+ """ Executes "cmd" and returns output """
+ if not os.path.exists(cmd):
+ raise Exception('File "' + path + '" not found!')
+ return
+ for arg in args:
+ cmd += ' ' + arg
+ return os.popen(cmd).readlines()
+
+ def delete_file(self, path):
+ """ Deletes file in "path" """
+ if os.path.exists(path):
+ os.unlink(path)
+
+ def make_exec_file(self, path):
+ """ Makes file in path u+rwx """
+ if not os.path.exists(path):
+ raise Exception('File "' + path + '" not found!')
+ return
+ os.chmod(path, stat.S_IXUSR + stat.S_IRUSR + stat.S_IWUSR)
+
+ def create_symlink(self, source, destination):
+ self.delete_file(destination)
+ os.symlink(source, destination)
+
+ def list_dir(self, path):
+ """ Lists path directory """
+ if not os.path.exists(path):
+ raise Exception("File " + path + " not found!")
+ return
+ else:
+ return os.listdir(path)
+ def path_exists(self, path):
+ return os.path.exists(path)
+ def real_path(self, path):
+ return os.path.realpath(path)
+
+class PrintSystem:
+ """ PrintSystem Class """
+
+ def __init__(self):
+ """ PrintSystem Constructor """
+ return
+
+ def verbose(self):
+ global verbose
+ verbose = True
+ return
+
+ def use_colors(self, usecolors):
+ global bold, lime, red, reset, yellow, error, warning, bullet,\
+ ok, highlight, notice
+ if usecolors:
+ # Text Colors
+ bold = '\033[1m'
+ lime = '\033[32m'
+ red = '\033[31m'
+ reset = '\033[0m'
+ yellow = '\033[1;33m'
+ blue = '\033[1;34m'
+ # Bullets
+ else:
+ bold = lime = red = reset = yellow = ''
+
+ error = bold + '(' + red + '!' + reset + bold + ')' + reset
+ warning = bold + '(' + yellow + '!' + reset + bold + ')' + reset
+ bullet = bold + '(' + lime + '*' + reset + bold + ')' + reset
+ notice = bold + '(' + blue + '*' + reset + bold + ')' + reset
+ ok = bold + '(' + lime + '>' + reset + bold + ')' + reset
+ highlight = lime + bold
+ # Glocal Print Functions
+ def print_line(self, line, _verbose = False):
+ """ Prints line with type"""
+ global verbose
+ if _verbose and not verbose:
+ return
+ print line
+ return
+
+ def print_table(self,list, _verbose = False):
+ """ Prints Lists of the form list[[a,b]] """
+ global verbose
+ if _verbose and not verbose:
+ return
+ for item in list:
+ print(' ' + item[0] + reset + '\r' + 3 * right + item[1])
+ return
+
+ def print_exception(self, exception, iswarning = False):
+ """ Prints Exceptions in a standart way """
+ if iswarning:
+ type = warning + ' Warning! '
+ else:
+ type = error + ' Error! '
+ self.print_line('\n' + type + str(exception) + '\n')
+
+ def format_action(self, action):
+ table = []
+ if action.parameters != '':
+ for line in action.usage:
+ table.append([line,''])
+ table.append(['',''])
+ count = 1
+ for option in action.options:
+ table.append([option[1] + space + \
+ eval(option[0]),''])
+ count += 1
+
+ return table
+ # Screen Functions
+ def print_ui(self, module = None, modules = None, \
+ action = None, args = None):
+ if module == None:
+ # uselect Usage
+ # uselect Options
+ self.print_usage()
+ self.print_line('')
+ self.print_options()
+ self.print_line('')
+ self.print_modules(modules)
+ self.print_line('')
+ elif action == None:
+ # Modules Usage
+ self.print_usage(module)
+ self.print_line('')
+ self.print_module(module)
+ self.print_line('')
+ # Modules Actions
+ self.print_actions(module)
+ self.print_line('')
+ elif args == None:
+ # Actions Usage
+ self.print_usage(module, action)
+ self.print_line('')
+ # Action
+ self.print_action(module, action)
+ self.print_line('')
+ else:
+ # This means Action Done
+ for line in action.output:
+ print(line)
+ return
+
+ def print_module(self, module):
+ self.print_line(bold + lime + 'Module' + space + reset \
+ + bold +module.name + lime + ':' + reset)
+ module.get_actions()
+ self.print_line('Author:' + space + module.author + space \
+ + 'Version:' + space + module.version)
+
+ def print_modules(self, modules):
+ self.print_line(lime + bold + 'Modules:' + reset)
+ list = []
+ for module in modules:
+ list.append([bold + module.name, bullet + space + module.description])
+ self.print_table(list)
+
+ def print_actions(self, module):
+ self.print_line(highlight + 'Actions:' + reset)
+ if len(module.actions) == 0:
+ print ' Module ' + module.name + \
+ ' has no actions!'
+ return
+ list = []
+ for action in module.actions:
+ self.print_table([[bold + action.name + reset, \
+ action.description]])
+
+ def print_action(self, module, action):
+ self.print_table([[bold + action.description + reset, '']])
+ self.print_line('')
+ self.print_table(self.format_action(action))
+
+ def print_version(self, version):
+ self.print_line(bold + 'Universal Select Tool - ' \
+ + lime + 'uselect' + reset)
+ self.print_line(bold + 'Version ' + reset + version + '\n')
+
+ def print_usage(self, module = None, action = None):
+ """ General Usage Printer """
+ if module != None:
+ module_name = module.name
+ else:
+ module_name = '<module>'
+ if action != None:
+ action_name = action.name
+ options = action.parameters
+ else:
+ action_name = '<action>'
+ options = '<options>'
+ self.print_line(bold + lime + 'Usage:' + reset + ' uselect <options> ' + module_name \
+ + space + action_name + space + options)
+
+ def print_options(self):
+ self.print_line(highlight + space + 'Options:' + reset)
+ self.print_table([ \
+ [bold + '-v', bullet + space + 'Verbose Mode'], \
+ [bold + '-nc', bullet + space + 'No Colors'], \
+ # [bold + '-profile', bullet + space + 'Profile Mode'], \
+ [bold + '-version', bullet + space + 'Version Information']])
+
diff --git a/umodule.py b/umodule.py
new file mode 100644
index 0000000..11bbf35
--- /dev/null
+++ b/umodule.py
@@ -0,0 +1,274 @@
+#!/usr/bin/env python
+# Copyright 1999-2009 Gentoo Foundation
+# Distributed under the terms of the GNU General Public License v2
+# Universal Select Tool
+# Uselect Modules/Actions Module
+# umodule.py mephx.x@gmail.com
+
+import re
+import os
+
+modules_dir = '/usr/share/uselect/modules/'
+
+class Action:
+
+
+ def __init__(self, name, lines, _filesystem):
+
+ self.filesystem = _filesystem
+ self.name = name
+ self.lines = lines
+ self.output = []
+ self.usage = []
+ self.options = []
+
+ for line in self.lines:
+ match = re.match('description "(.*)"', line.lstrip())
+ if match:
+ self.description = match.group(1)
+ continue
+ match = re.match('type (.*)', line.lstrip())
+ if match:
+ type = match.group(1)
+ continue
+
+ if type == 'runnable':
+ self.__class__ = Runnable
+ elif type == 'sym':
+ if filesystem.uid != 'root':
+ self.__class__ = Path
+ else:
+ self.__class__ = Sym
+ self.build()
+
+class Runnable(Action):
+
+ def do_action(self, args):
+ path = '/tmp/' + self.filename
+ self.filesystem.write_file(path, self.code)
+ self.filesystem.make_exec_file(path)
+ for line in self.filesystem.execute_cmd(path,args):
+ self.output.append(line[:-1])
+ self.filesystem.delete_file(path)
+ for line in self.output:
+ self.options.append(['bold', line])
+
+ def get_code(self):
+ i = 0
+ for line in self.lines:
+ match = re.match('file (.*) {', line.lstrip())
+ if match:
+ ident = 1
+ for char in line:
+ if char == '\t':
+ ident += 1
+ self.filename = match.group(1)
+ for line in self.lines[i+1:]:
+ line = line.rstrip()
+ line = line.replace('\t', '', ident)
+ match = re.match('} ' + self.filename, line)
+ if match:
+ self.code.append('')
+ break
+ self.code.append(line)
+ i += 1
+
+ def build(self):
+ self.code = []
+ self.get_code()
+ for line in self.lines:
+ match = re.match('parameters "(.*)"', line.lstrip())
+ if match:
+ self.parameters = match.group(1)
+ continue
+ match = re.match('usage "(.*)"', line.lstrip())
+ if match:
+ self.usage.append(match.group(1))
+ continue
+
+class Link:
+
+ def __init__(self, name, source_dir, source_regexp, source_target, \
+ destination, _filesystem):
+
+ self.name = name
+ self.destination = destination
+ self.targets = []
+ self.status = []
+ self.filesystem = _filesystem
+
+ for dir in self.filesystem.list_dir(source_dir):
+ match = re.match(source_regexp, dir)
+ if match:
+ source = source_dir + match.group(0) + source_target
+ self.targets.append(source)
+ if self.filesystem.path_exists(destination):
+ if self.filesystem.real_path( \
+ self.filesystem.environment + self.name) == \
+ source:
+ self.status.append('notice')
+ elif self.filesystem.real_path(destination) == source:
+ self.status.append('ok')
+ else:
+ self.status.append('warning')
+
+ else:
+ self.status.append('error')
+ return
+
+class Sym(Action):
+
+
+ def get_links(self):
+ for line in self.lines:
+ match = re.match('sym (.*) (.*) (.*) (.*) (.*)', line.lstrip())
+ if match:
+ name = match.group(1)
+ source_dir = match.group(3)
+ source_regexp = match.group(4)
+ if match.group(5) == '*':
+ source_target = ''
+ else:
+ source_target = match.group(5)
+ destination = match.group(2)
+ self.links.append(Link(name, source_dir, source_regexp,\
+ source_target, destination, self.filesystem))
+
+ def do_action(self, args):
+
+ if len(args) != 0:
+ if args[0] == 'clear':
+ for link in self.links:
+ self.filesystem.delete_file(link.destination)
+ elif len(args) >= 1:
+ targets = []
+ option = int(args[0]) -1
+ for link in self.links:
+ for i in range(len(link.targets)):
+ targets.append([link.targets[i], \
+ link.destination])
+ if option >= 0 and option < len(targets):
+ self.filesystem.create_symlink(targets[option][0], \
+ targets[option][1])
+ self.output.append('Setting ' + targets[option][0] \
+ + ' success!')
+ else:
+ raise UserWarning('Invalid Option "' \
+ + args[0] + '"!')
+ else:
+ raise UserWarning('Invalid Option "' + args[0] \
+ + '"!')
+ else:
+ for link in self.links:
+ for i in range(len(link.targets)):
+ self.options.append([link.status[i],str(i+1) + ' - ' + \
+ link.targets[i]])
+ self.parameters = '<target>'
+ self.usage.append('Available ' + self.name + ' targets:' )
+
+ def build(self):
+ self.links = []
+ self.get_links()
+
+class Path(Action, Sym):
+
+ def do_action(self, args):
+ if len(args) != 0:
+ if args[0] == 'clear':
+ home = self.filesystem.get_home()
+ for link in self.links:
+ self.filesystem.delete_file(home + '.uselect/bin/' \
+ + link.name)
+ elif len(args) >= 1:
+ options = []
+ choice = int(args[0]) - 1
+ for link in self.links:
+ for i in range(len(link.targets)):
+ options.append([link.targets[i], \
+ link.destination])
+ if choice >= 0 and choice < len(options):
+ self.filesystem.create_symlink( \
+ options[choice][0],
+ self.filesystem.environment + \
+ link.name)
+ self.output.append('Setting ' + options[choice][0] \
+ + ' success!')
+ else:
+ raise UserWarning('Invalid Option "' \
+ + args[0] + '"!')
+ else:
+ raise UserWarning('Invalid Option "' + args[0] \
+ + '"!')
+ else:
+ for link in self.links:
+ for i in range(len(link.targets)):
+ self.options.append([link.status[i],str(i+1) + ' - ' + \
+ link.targets[i]])
+ self.parameters = '<target>'
+ self.usage.append('Available ' + self.name + ' targets:' )
+ return
+
+class Module():
+
+ def __init__(self, name, _filesystem):
+ global filesystem
+ filesystem = _filesystem
+ self.name = name
+ self.version = 'Unknown'
+ self.author = 'Anonymous'
+ self.description = name + ' has no description! '
+ self.path = modules_dir + self.name + '.uselect'
+ self.lines = filesystem.read_file(self.path)
+ self.parse_module(name)
+ self.actions = []
+
+ def parse_module(self, name):
+ for line in self.lines:
+ line = line.lstrip()
+ match = re.match('description "(.*)"', line)
+ if match:
+ self.description = match.group(1)
+ continue
+ match = re.match('version "(.*)"', line)
+ if match:
+ self.version = match.group(1)
+ continue
+ match = re.match('author "(.*)"', line)
+ if match:
+ self.author = match.group(1)
+ continue
+ match = re.match('} ' + name, line)
+ if match:
+ break
+
+ def get_action(self, name):
+ i = 0
+ self.get_actions()
+ for action in self.actions:
+ if action.name == name:
+ return action
+ raise Exception('No such action "' + name + '"!')
+
+ def get_actions(self):
+ i = 0
+ for line in self.lines:
+ match = re.match('(\w*) action (\w*)', line.lstrip())
+ if match:
+ wideness = match.group(1)
+ if wideness == "system" and filesystem.uid != "root":
+ continue
+ name = match.group(2)
+ u = 0
+ for line in self.lines[i:]:
+ match = re.match('} ' + name + '\w*', line)
+ if match:
+ lines = self.lines[i:i+u+1]
+ action = Action(name, lines, filesystem)
+ self.actions.append(action)
+ break
+ u += 1
+ if name == '(\w*)':
+ break
+ i += 1
+
+
diff --git a/uselect.py b/uselect.py
new file mode 100755
index 0000000..4938176
--- /dev/null
+++ b/uselect.py
@@ -0,0 +1,99 @@
+#!/usr/bin/env python
+# Copyright 1999-2009 Gentoo Foundation
+# Distributed under the terms of the GNU General Public License v2
+# Universal Select Tool
+# Base Module
+# umodule.py mephx.x@gmail.com
+
+import os
+import re
+import sys
+import stat
+import string
+import traceback
+
+from umodule import Module
+from uio import PrintSystem
+from uio import FileSystem
+
+verbose = False
+
+version = '0.2'
+modules_dir = '/usr/share/uselect/modules/'
+
+class UniversalSelectTool:
+
+ printsystem = PrintSystem()
+ filesystem = FileSystem()
+
+ def __init__(self):
+ return
+
+ def get_modules(self):
+ list = self.filesystem.list_dir(modules_dir)
+ self.modules = []
+ for file in list:
+ match = re.match('(.*).uselect', file)
+ if match:
+ self.modules.append(Module(match.group(1), self.filesystem))
+
+ def get_module(self, name):
+ if not os.path.exists(modules_dir + name + '.uselect'):
+ raise Exception('Module ' + name + ' not found!')
+ return
+ else:
+ module = Module(name, self.filesystem)
+ return module
+
+ def parse_argv(self, argv):
+ global profile, verbose, version
+ module = None
+ modules = None
+ action = None
+ args = None
+ self.printsystem.use_colors(True)
+ for arg in argv:
+ if arg == '-v':
+ verbose = True
+ self.printsystem.verbose()
+ argv = argv[1:]
+ elif arg == '-nc':
+ self.printsystem.use_colors(False)
+ argv = argv[1:]
+ elif arg == '-version':
+ self.printsystem.print_version(version)
+ argv = argv[1:]
+ if len(argv) < 1:
+ self.get_modules()
+ modules = self.modules
+ elif len(argv) == 1:
+ module = self.get_module(argv[0])
+ elif len(argv) >= 2:
+ module = self.get_module(argv[0])
+ action = module.get_action(argv[1])
+ action.do_action(argv[2:])
+ if len(argv) == 2:
+ argv = None
+ else:
+ argv = argv[2:]
+
+ return [module, modules, argv, action]
+
+
+def main():
+ uselect = UniversalSelectTool()
+ try:
+ list = uselect.parse_argv(sys.argv[1:])
+ uselect.printsystem.print_ui(module = list[0], \
+ modules = list[1], args = list[2], action = list[3])
+ except UserWarning, warning:
+ uselect.printsystem.print_exception(warning, True)
+ except Exception, exception:
+ uselect.printsystem.print_exception(exception)
+ if verbose:
+ traceback.print_exc()
+ printsystem.print_line('')
+ exit(1)
+ exit(0)
+
+if __name__ == '__main__': main()