#! /usr/bin/env python # synergy -- mouse and keyboard sharing utility # Copyright (C) 2009 Chris Schoeneman, Nick Bolton, Sorin Sbarnea # # This package is free software; you can redistribute it and/or # modify it under the terms of the GNU General Public License # found in the file COPYING that should have accompanied this file. # # This package is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . # hm.py: 'Help Me', is a simple wrapper for all build tools. # # This script was created for the Synergy project. # http://synergy-foss.org/ # # The idea behind this is to simplify the build system, # however, it's not a dependancy of building Synergy. # In other words, you don't need to use this script! # # If you don't wish to run this script, simply run: # cmake . # make # This will create an in-source UNIX Makefile. import sys, os sys.path.append('tools') # if old build src dir exists, move it, as this will now be used for build # output. if os.path.exists('build/toolchain.py'): print "Removing legacy build dir." os.rename('build', 'build.old') from build import toolchain from getopt import gnu_getopt # minimum required version requiredMajor = 2 requiredMinor = 3 # options used by all commands globalOptions = 'v' globalOptionsLong = ['no-prompts', 'generator=', 'verbose', 'make-gui'] # list of valid commands as keys. the values are optarg strings, but most # are None for now (this is mainly for extensibility) cmd_opt_dict = { 'about' : ['', []], 'setup' : ['g:', []], 'configure' : ['g:dr', ['debug', 'release', 'game-device', 'vnc', 'mac-sdk=']], 'build' : ['dr', ['debug', 'release']], 'clean' : ['dr', ['debug', 'release']], 'update' : ['', []], 'install' : ['', []], 'doxygen' : ['', []], 'dist' : ['', ['vcredist-dir=', 'qt-dir=']], 'distftp' : ['', ['host=', 'user=', 'pass=', 'dir=']], 'kill' : ['', []], 'usage' : ['', []], 'revision' : ['', []], 'reformat' : ['', []], 'open' : ['', []], 'genlist' : ['', []], 'reset' : ['', []], 'sign' : ['', ['pfx=', 'pwd=', 'dist']] } # aliases to valid commands cmd_alias_dict = { 'info' : 'about', 'help' : 'usage', 'package' : 'dist', 'docs' : 'doxygen', 'make' : 'build', 'cmake' : 'configure', } def complete_command(arg): completions = [] for cmd, optarg in cmd_opt_dict.iteritems(): # if command was matched fully, return only this, so that # if `dist` is typed, it will return only `dist` and not # `dist` and `distftp` for example. if cmd == arg: return [cmd,] if cmd.startswith(arg): completions.append(cmd) for alias, cmd in cmd_alias_dict.iteritems(): # don't know if this will work just like above, but it's # probably worth adding. if alias == arg: return [alias,] if alias.startswith(arg): completions.append(alias) return completions def start_cmd(argv): cmd_arg = '' if len(argv) > 1: cmd_arg = argv[1] # change common help args to help command if cmd_arg in ('--help', '-h', '--usage', '-u', '/?'): cmd_arg = 'usage' completions = complete_command(cmd_arg) if cmd_arg and len(completions) > 0: if len(completions) == 1: # get the only completion (since in this case we have 1) cmd = completions[0] # build up the first part of the map (for illustrative purposes) cmd_map = list() if cmd_arg != cmd: cmd_map.append(cmd_arg) cmd_map.append(cmd) # map an alias to the command, and build up the map if cmd in cmd_alias_dict.keys(): alias = cmd if cmd_arg == cmd: cmd_map.append(alias) cmd = cmd_alias_dict[cmd] cmd_map.append(cmd) # show command map to avoid confusion if len(cmd_map) != 0: print 'Mapping command: %s' % ' -> '.join(cmd_map) run_cmd(cmd, argv[2:]) return 0 else: print ( 'Command `%s` too ambiguous, ' 'could mean any of: %s' ) % (cmd_arg, ', '.join(completions)) else: if len(argv) == 1: print 'No command specified, showing usage.\n' else: print 'Command not recognised: %s\n' % cmd_arg run_cmd('usage') # generic error code if not returned sooner return 1 def run_cmd(cmd, argv = []): verbose = False try: options_pair = cmd_opt_dict[cmd] options = globalOptions + options_pair[0] options_long = [] options_long.extend(globalOptionsLong) options_long.extend(options_pair[1]) opts, args = gnu_getopt(argv, options, options_long) for o, a in opts: if o in ('-v', '--verbose'): verbose = True # pass args and optarg data to command handler, which figures out # how to handle the arguments handler = toolchain.CommandHandler(argv, opts, args, verbose) # use reflection to get the function pointer cmd_func = getattr(handler, cmd) cmd_func() except: if not verbose: # print friendly error for users sys.stderr.write('Error: ' + sys.exc_info()[1].__str__() + '\n') sys.exit(1) else: # if user wants to be verbose let python do it's thing raise def main(argv): if sys.version_info < (requiredMajor, requiredMinor): print ('Python version must be at least ' + str(requiredMajor) + '.' + str(requiredMinor) + ', but is ' + str(sys.version_info[0]) + '.' + str(sys.version_info[1])) sys.exit(1) try: start_cmd(argv) except KeyboardInterrupt: print '\n\nUser aborted, exiting.' # Start the program. main(sys.argv)