mirror of
https://github.com/erkin/ponysay.git
synced 2024-11-25 05:47:59 +01:00
Merge pull request #210 from Feuermurmel/setup
Fix for #209 and assorted enhancements.
This commit is contained in:
commit
9e555ff3e0
1 changed files with 135 additions and 91 deletions
226
setup.py
226
setup.py
|
@ -48,7 +48,7 @@ SYMBOLIC = 'symbolic'
|
||||||
class Setup():
|
class Setup():
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
usage_script = '\033[34;1msetup.py\033[21;39m'
|
usage_script = '\033[34;1msetup.py\033[21;39m'
|
||||||
usage_help = '(version | help)'
|
usage_help = '(--version | --help)'
|
||||||
usage_proc = '[\033[4mconfigurations\033[24m] ([build] | prebuilt | install | (uninstall|clean)[-old] | view)'
|
usage_proc = '[\033[4mconfigurations\033[24m] ([build] | prebuilt | install | (uninstall|clean)[-old] | view)'
|
||||||
|
|
||||||
usage = '%s %s\n%s %s' % (usage_script, usage_help, usage_script, usage_proc)
|
usage = '%s %s\n%s %s' % (usage_script, usage_help, usage_script, usage_proc)
|
||||||
|
@ -240,16 +240,19 @@ class Setup():
|
||||||
self.free = False
|
self.free = False
|
||||||
def checkFreedom():
|
def checkFreedom():
|
||||||
if self.free is None:
|
if self.free is None:
|
||||||
if (opts.opts['--version'] is None) and ((len(opts.files) != 1) or (opts.files[0] != 'version')):
|
print()
|
||||||
print('')
|
print('You need to select your freedom, add --freedom=strict or --freedom=partial.')
|
||||||
print('You need to select your freedom, add --freedom=strict or --freedom=partial.')
|
print()
|
||||||
print('')
|
print('--freedom=strict will install only ponies that are completely free.')
|
||||||
print('--freedom=strict will install only ponies that are completely free.')
|
print('--freedom=partial will install all ponies, even if they are not free.')
|
||||||
print('--freedom=partial will install all ponies, even if they are not free.')
|
print()
|
||||||
print('')
|
print()
|
||||||
print('')
|
exit(255)
|
||||||
exit(255)
|
|
||||||
|
def setup_config():
|
||||||
|
self.viewconf(conf)
|
||||||
|
os.umask(0o022)
|
||||||
|
|
||||||
if (opts.opts['---DESTDIR'] is not None) and (opts.opts['--dest-dir'] is None):
|
if (opts.opts['---DESTDIR'] is not None) and (opts.opts['--dest-dir'] is None):
|
||||||
destdir = opts.opts['---DESTDIR'][0]
|
destdir = opts.opts['---DESTDIR'][0]
|
||||||
if len(destdir) > 0:
|
if len(destdir) > 0:
|
||||||
|
@ -259,51 +262,59 @@ class Setup():
|
||||||
prefix = opts.opts['---PREFIX'][0]
|
prefix = opts.opts['---PREFIX'][0]
|
||||||
if len(prefix) > 0:
|
if len(prefix) > 0:
|
||||||
opts.opts['--prefix'] = [prefix]
|
opts.opts['--prefix'] = [prefix]
|
||||||
|
|
||||||
if (len(opts.files) > 1) or (opts.opts['--help'] is not None) or ((len(opts.files) == 1) and (opts.files[0] == 'help')):
|
if opts.opts['--help'] is not None:
|
||||||
opts.help()
|
opts.help()
|
||||||
elif (opts.opts['--version'] is not None) or ((len(opts.files) == 1) and (opts.files[0] == 'version')):
|
elif opts.opts['--version'] is not None:
|
||||||
print('Ponysay %s installer' % (PONYSAY_VERSION))
|
print('Ponysay %s installer' % (PONYSAY_VERSION))
|
||||||
|
elif len(opts.files) != 1:
|
||||||
|
opts.print_fatal('A single command is expected on the command line.')
|
||||||
|
opts.usage()
|
||||||
else:
|
else:
|
||||||
if len(opts.files) == 0:
|
|
||||||
opts.files = ['build']
|
|
||||||
method = opts.files[0]
|
method = opts.files[0]
|
||||||
if method == 'clean': self.clean()
|
if method == 'clean': self.clean()
|
||||||
elif method == 'clean-old': self.cleanOld()
|
elif method == 'clean-old': self.cleanOld()
|
||||||
else:
|
else:
|
||||||
conf = self.configure(opts.opts)
|
conf = self.configure(opts.opts)
|
||||||
self.viewconf(conf)
|
|
||||||
os.umask(0o022)
|
|
||||||
|
|
||||||
if method == 'build':
|
if method == 'build':
|
||||||
checkFreedom()
|
checkFreedom()
|
||||||
|
setup_config()
|
||||||
self.build(conf)
|
self.build(conf)
|
||||||
|
|
||||||
elif method == 'prebuilt':
|
elif method == 'prebuilt':
|
||||||
checkFreedom()
|
checkFreedom()
|
||||||
|
setup_config()
|
||||||
self.applyDestDir(conf)
|
self.applyDestDir(conf)
|
||||||
self.install(conf)
|
self.install(conf)
|
||||||
|
|
||||||
elif method == 'install':
|
elif method == 'install':
|
||||||
checkFreedom()
|
checkFreedom()
|
||||||
|
setup_config()
|
||||||
self.build(conf)
|
self.build(conf)
|
||||||
self.applyDestDir(conf)
|
self.applyDestDir(conf)
|
||||||
self.install(conf)
|
self.install(conf)
|
||||||
self.clean()
|
self.clean()
|
||||||
|
|
||||||
elif method == 'uninstall':
|
elif method == 'uninstall':
|
||||||
|
setup_config()
|
||||||
self.uninstall(conf)
|
self.uninstall(conf)
|
||||||
|
|
||||||
elif method == 'uninstall-old':
|
elif method == 'uninstall-old':
|
||||||
|
setup_config()
|
||||||
self.uninstallOld(conf)
|
self.uninstallOld(conf)
|
||||||
|
|
||||||
elif not method == 'view':
|
elif method == 'view':
|
||||||
opts.help()
|
setup_config()
|
||||||
|
else:
|
||||||
'''
|
opts.print_fatal('Unknown command: {}', method)
|
||||||
Display configurations
|
opts.usage()
|
||||||
'''
|
|
||||||
def viewconf(self, conf):
|
def viewconf(self, conf):
|
||||||
|
'''
|
||||||
|
Display configurations
|
||||||
|
'''
|
||||||
|
|
||||||
RED = '\033[31m%s\033[39m'
|
RED = '\033[31m%s\033[39m'
|
||||||
GREEN = '%s\033[32m%s\033[39m'
|
GREEN = '%s\033[32m%s\033[39m'
|
||||||
YELLOW = '\033[33m%s\033[39m'
|
YELLOW = '\033[33m%s\033[39m'
|
||||||
|
@ -351,11 +362,12 @@ class Setup():
|
||||||
else: print(RED % ('Installing \033[1mnot\033[21m only fully free parts of the package'))
|
else: print(RED % ('Installing \033[1mnot\033[21m only fully free parts of the package'))
|
||||||
|
|
||||||
print()
|
print()
|
||||||
|
|
||||||
'''
|
|
||||||
Compile ponysay
|
|
||||||
'''
|
|
||||||
def build(self, conf):
|
def build(self, conf):
|
||||||
|
'''
|
||||||
|
Compile ponysay
|
||||||
|
'''
|
||||||
|
|
||||||
print('\033[1;34m::\033[39mCompiling...\033[21m')
|
print('\033[1;34m::\033[39mCompiling...\033[21m')
|
||||||
|
|
||||||
def compressCommand(ext):
|
def compressCommand(ext):
|
||||||
|
@ -556,11 +568,12 @@ class Setup():
|
||||||
Popen(params, stdin=PIPE, stdout=PIPE, stderr=PIPE).communicate()
|
Popen(params, stdin=PIPE, stdout=PIPE, stderr=PIPE).communicate()
|
||||||
|
|
||||||
print()
|
print()
|
||||||
|
|
||||||
'''
|
|
||||||
Install compiled ponysay
|
|
||||||
'''
|
|
||||||
def install(self, conf):
|
def install(self, conf):
|
||||||
|
'''
|
||||||
|
Install compiled ponysay
|
||||||
|
'''
|
||||||
|
|
||||||
print('\033[1;34m::\033[39mInstalling...\033[21m')
|
print('\033[1;34m::\033[39mInstalling...\033[21m')
|
||||||
|
|
||||||
dests = []
|
dests = []
|
||||||
|
@ -642,11 +655,12 @@ class Setup():
|
||||||
for file in miscfiles:
|
for file in miscfiles:
|
||||||
self.cp(False, file[0], [conf[file[0]]], Setup.validateFreedom if self.free else None)
|
self.cp(False, file[0], [conf[file[0]]], Setup.validateFreedom if self.free else None)
|
||||||
print()
|
print()
|
||||||
|
|
||||||
'''
|
|
||||||
Uninstall ponysay
|
|
||||||
'''
|
|
||||||
def uninstall(self, conf):
|
def uninstall(self, conf):
|
||||||
|
'''
|
||||||
|
Uninstall ponysay
|
||||||
|
'''
|
||||||
|
|
||||||
print('\033[1;34m::\033[39mUninstalling...\033[21m')
|
print('\033[1;34m::\033[39mUninstalling...\033[21m')
|
||||||
|
|
||||||
(files, dirs, infos) = ([], [], [])
|
(files, dirs, infos) = ([], [], [])
|
||||||
|
@ -699,11 +713,12 @@ class Setup():
|
||||||
|
|
||||||
self.removeLists(files, dirs)
|
self.removeLists(files, dirs)
|
||||||
print()
|
print()
|
||||||
|
|
||||||
'''
|
|
||||||
Uninstall file ponysay no longer uses
|
|
||||||
'''
|
|
||||||
def uninstallOld(self, conf):
|
def uninstallOld(self, conf):
|
||||||
|
'''
|
||||||
|
Uninstall file ponysay no longer uses
|
||||||
|
'''
|
||||||
|
|
||||||
print('\033[1;34m::\033[39mUninstalling old files...\033[21m')
|
print('\033[1;34m::\033[39mUninstalling old files...\033[21m')
|
||||||
|
|
||||||
instdir = conf['~prefix~'] + '/usr'
|
instdir = conf['~prefix~'] + '/usr'
|
||||||
|
@ -719,11 +734,12 @@ class Setup():
|
||||||
|
|
||||||
self.removeLists(files, dirs)
|
self.removeLists(files, dirs)
|
||||||
print()
|
print()
|
||||||
|
|
||||||
'''
|
|
||||||
Remove compiled files
|
|
||||||
'''
|
|
||||||
def clean(self):
|
def clean(self):
|
||||||
|
'''
|
||||||
|
Remove compiled files
|
||||||
|
'''
|
||||||
|
|
||||||
print('\033[1;34m::\033[39mCleaning...\033[21m')
|
print('\033[1;34m::\033[39mCleaning...\033[21m')
|
||||||
|
|
||||||
files = ['ponysay.info', 'ponysay.info.gz', 'ponysay.info.xz', 'ponysay.pdf.gz', 'ponysay.pdf.xz', 'ponysay.install', 'ponysay.zip']
|
files = ['ponysay.info', 'ponysay.info.gz', 'ponysay.info.xz', 'ponysay.pdf.gz', 'ponysay.pdf.xz', 'ponysay.install', 'ponysay.zip']
|
||||||
|
@ -746,10 +762,11 @@ class Setup():
|
||||||
self.removeLists(files, dirs)
|
self.removeLists(files, dirs)
|
||||||
print()
|
print()
|
||||||
|
|
||||||
'''
|
|
||||||
Remove compiled files ponysay is no longer compiling
|
|
||||||
'''
|
|
||||||
def cleanOld(self):
|
def cleanOld(self):
|
||||||
|
'''
|
||||||
|
Remove compiled files ponysay is no longer compiling
|
||||||
|
'''
|
||||||
|
|
||||||
print('\033[1;34m::\033[39mCleaning old files...\033[21m')
|
print('\033[1;34m::\033[39mCleaning old files...\033[21m')
|
||||||
|
|
||||||
files = ['truncater', 'ponysaytruncater', 'ponysay.py.install', 'ponysay.install~', 'ponysay.zip']
|
files = ['truncater', 'ponysaytruncater', 'ponysay.py.install', 'ponysay.install~', 'ponysay.zip']
|
||||||
|
@ -763,11 +780,12 @@ class Setup():
|
||||||
|
|
||||||
self.removeLists(files, dirs)
|
self.removeLists(files, dirs)
|
||||||
print()
|
print()
|
||||||
|
|
||||||
'''
|
|
||||||
Removes listed files and directories
|
|
||||||
'''
|
|
||||||
def removeLists(self, files, dirs):
|
def removeLists(self, files, dirs):
|
||||||
|
'''
|
||||||
|
Removes listed files and directories
|
||||||
|
'''
|
||||||
|
|
||||||
for file in files:
|
for file in files:
|
||||||
if os.path.isfile(file) or os.path.islink(file):
|
if os.path.isfile(file) or os.path.islink(file):
|
||||||
print('Unlinking file %s' % (file))
|
print('Unlinking file %s' % (file))
|
||||||
|
@ -792,12 +810,13 @@ class Setup():
|
||||||
os.rmdir(dir)
|
os.rmdir(dir)
|
||||||
else:
|
else:
|
||||||
break;
|
break;
|
||||||
|
|
||||||
'''
|
|
||||||
Check whether a file is fully free
|
|
||||||
'''
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def validateFreedom(filename):
|
def validateFreedom(filename):
|
||||||
|
'''
|
||||||
|
Check whether a file is fully free
|
||||||
|
'''
|
||||||
|
|
||||||
if not os.path.isdir(filename):
|
if not os.path.isdir(filename):
|
||||||
if filename.endswith('.pony') and (filename != '.pony') and not filename.endswith('/.pony'):
|
if filename.endswith('.pony') and (filename != '.pony') and not filename.endswith('/.pony'):
|
||||||
with open(filename, 'rb') as file:
|
with open(filename, 'rb') as file:
|
||||||
|
@ -812,11 +831,12 @@ class Setup():
|
||||||
return line[1].lower() == 'yes'
|
return line[1].lower() == 'yes'
|
||||||
return False
|
return False
|
||||||
return True
|
return True
|
||||||
|
|
||||||
'''
|
|
||||||
Copys a files or directory to multiple destinations
|
|
||||||
'''
|
|
||||||
def cp(self, recursive, source, destinations, validatehook = None):
|
def cp(self, recursive, source, destinations, validatehook = None):
|
||||||
|
'''
|
||||||
|
Copys a files or directory to multiple destinations
|
||||||
|
'''
|
||||||
|
|
||||||
if validatehook is not None:
|
if validatehook is not None:
|
||||||
if not validatehook(source):
|
if not validatehook(source):
|
||||||
print('Ignoring installation of file %s (did not pass validation process made by setup settings)' % source)
|
print('Ignoring installation of file %s (did not pass validation process made by setup settings)' % source)
|
||||||
|
@ -890,11 +910,12 @@ class Setup():
|
||||||
if os.path.exists(dest):
|
if os.path.exists(dest):
|
||||||
os.unlink(dest)
|
os.unlink(dest)
|
||||||
self.symlink(target, dest)
|
self.symlink(target, dest)
|
||||||
|
|
||||||
'''
|
|
||||||
Create a symlink with a relative path
|
|
||||||
'''
|
|
||||||
def symlink(self, target, dest):
|
def symlink(self, target, dest):
|
||||||
|
'''
|
||||||
|
Create a symlink with a relative path
|
||||||
|
'''
|
||||||
|
|
||||||
if target.startswith('./') or target.startswith('../'):
|
if target.startswith('./') or target.startswith('../'):
|
||||||
os.symlink(target, dest)
|
os.symlink(target, dest)
|
||||||
elif '/' not in target:
|
elif '/' not in target:
|
||||||
|
@ -914,10 +935,11 @@ class Setup():
|
||||||
|
|
||||||
os.symlink('/'.join(targets), dest)
|
os.symlink('/'.join(targets), dest)
|
||||||
|
|
||||||
'''
|
|
||||||
Parses configurations
|
|
||||||
'''
|
|
||||||
def configure(self, opts):
|
def configure(self, opts):
|
||||||
|
'''
|
||||||
|
Parses configurations
|
||||||
|
'''
|
||||||
|
|
||||||
(defaults, conf) = ({}, {})
|
(defaults, conf) = ({}, {})
|
||||||
|
|
||||||
for command in commands:
|
for command in commands:
|
||||||
|
@ -1070,15 +1092,18 @@ class Setup():
|
||||||
|
|
||||||
ARGUMENTLESS = 0
|
ARGUMENTLESS = 0
|
||||||
ARGUMENTED = 1
|
ARGUMENTED = 1
|
||||||
'''
|
|
||||||
Simple argument parser, a strip down of the one in ponysay and slitly modified
|
|
||||||
'''
|
|
||||||
class ArgParser():
|
class ArgParser():
|
||||||
'''
|
'''
|
||||||
Constructor.
|
Simple argument parser, a strip down of the one in ponysay and slitly modified
|
||||||
The short description is printed on same line as the program name
|
|
||||||
'''
|
'''
|
||||||
|
|
||||||
def __init__(self, program, description, usage, longdescription = None):
|
def __init__(self, program, description, usage, longdescription = None):
|
||||||
|
'''
|
||||||
|
Constructor.
|
||||||
|
The short description is printed on same line as the program name
|
||||||
|
'''
|
||||||
|
|
||||||
self.__program = program
|
self.__program = program
|
||||||
self.__description = description
|
self.__description = description
|
||||||
self.__usage = usage
|
self.__usage = usage
|
||||||
|
@ -1086,27 +1111,30 @@ class ArgParser():
|
||||||
self.__arguments = []
|
self.__arguments = []
|
||||||
(self.opts, self.optmap) = ({}, {})
|
(self.opts, self.optmap) = ({}, {})
|
||||||
|
|
||||||
'''
|
|
||||||
Add option that takes no arguments
|
|
||||||
'''
|
|
||||||
def add_argumentless(self, alternatives, help = None):
|
def add_argumentless(self, alternatives, help = None):
|
||||||
|
'''
|
||||||
|
Add option that takes no arguments
|
||||||
|
'''
|
||||||
|
|
||||||
ARGUMENTLESS
|
ARGUMENTLESS
|
||||||
self.__arguments.append((ARGUMENTLESS, alternatives, None, help))
|
self.__arguments.append((ARGUMENTLESS, alternatives, None, help))
|
||||||
(stdalt, self.opts[stdalt]) = (alternatives[0], None)
|
(stdalt, self.opts[stdalt]) = (alternatives[0], None)
|
||||||
for alt in alternatives: self.optmap[alt] = (stdalt, ARGUMENTLESS)
|
for alt in alternatives: self.optmap[alt] = (stdalt, ARGUMENTLESS)
|
||||||
|
|
||||||
'''
|
|
||||||
Add option that takes one argument
|
|
||||||
'''
|
|
||||||
def add_argumented(self, alternatives, arg, help = None):
|
def add_argumented(self, alternatives, arg, help = None):
|
||||||
|
'''
|
||||||
|
Add option that takes one argument
|
||||||
|
'''
|
||||||
|
|
||||||
self.__arguments.append((ARGUMENTED, alternatives, arg, help))
|
self.__arguments.append((ARGUMENTED, alternatives, arg, help))
|
||||||
(stdalt, self.opts[stdalt]) = (alternatives[0], None)
|
(stdalt, self.opts[stdalt]) = (alternatives[0], None)
|
||||||
for alt in alternatives: self.optmap[alt] = (stdalt, ARGUMENTED)
|
for alt in alternatives: self.optmap[alt] = (stdalt, ARGUMENTED)
|
||||||
|
|
||||||
'''
|
|
||||||
Parse arguments
|
|
||||||
'''
|
|
||||||
def parse(self, argv = sys.argv):
|
def parse(self, argv = sys.argv):
|
||||||
|
'''
|
||||||
|
Parse arguments
|
||||||
|
'''
|
||||||
|
|
||||||
self.argcount = len(argv) - 1
|
self.argcount = len(argv) - 1
|
||||||
self.files = []
|
self.files = []
|
||||||
(argqueue, optqueue, get) = ([], [], False)
|
(argqueue, optqueue, get) = ([], [], False)
|
||||||
|
@ -1129,13 +1157,13 @@ class ArgParser():
|
||||||
optqueue.append(arg_opt)
|
optqueue.append(arg_opt)
|
||||||
argqueue.append(arg[arg.index('=') + 1:])
|
argqueue.append(arg[arg.index('=') + 1:])
|
||||||
else:
|
else:
|
||||||
sys.stderr.write('%s: fatal: unrecognised option %s. see --help or the manual\n' % (self.__program, arg))
|
self.print_fatal('Unrecognized option {}. Use --help or consult the manual.', arg)
|
||||||
exit(-1)
|
exit(-1)
|
||||||
elif (arg in self.optmap) and (self.optmap[arg][1] == ARGUMENTED):
|
elif (arg in self.optmap) and (self.optmap[arg][1] == ARGUMENTED):
|
||||||
optqueue.append(arg)
|
optqueue.append(arg)
|
||||||
get = True
|
get = True
|
||||||
else:
|
else:
|
||||||
sys.stderr.write('%s: fatal: unrecognised option %s. see --help or the manual\n' % (self.__program, arg))
|
self.print_fatal('Unrecognized option {}. Use --help or consult the manual.', arg)
|
||||||
exit(-1)
|
exit(-1)
|
||||||
else:
|
else:
|
||||||
self.files.append(arg)
|
self.files.append(arg)
|
||||||
|
@ -1149,14 +1177,17 @@ class ArgParser():
|
||||||
if (opt not in self.opts) or (self.opts[opt] is None):
|
if (opt not in self.opts) or (self.opts[opt] is None):
|
||||||
self.opts[opt] = [arg]
|
self.opts[opt] = [arg]
|
||||||
else:
|
else:
|
||||||
sys.stderr.write('%s: fatal: duplicate option %s\n' % (self.__program, arg))
|
self.print_fatal('duplicate option {}', arg)
|
||||||
exit(-1)
|
exit(-1)
|
||||||
|
|
||||||
'''
|
def print_fatal(self, message, *args):
|
||||||
Prints a colourful help message
|
sys.stderr.write('{}: fatal: {}\n'.format(self.__program, message.format(*args)))
|
||||||
'''
|
|
||||||
def help(self):
|
def usage(self):
|
||||||
print('\033[1m%s\033[21m - %s\n' % (self.__program, self.__description))
|
'''
|
||||||
|
Print a short usage message.
|
||||||
|
'''
|
||||||
|
|
||||||
if self.__longdescription is not None:
|
if self.__longdescription is not None:
|
||||||
print(self.__longdescription)
|
print(self.__longdescription)
|
||||||
print()
|
print()
|
||||||
|
@ -1165,8 +1196,21 @@ class ArgParser():
|
||||||
for line in self.__usage.split('\n'):
|
for line in self.__usage.split('\n'):
|
||||||
if first: first = False
|
if first: first = False
|
||||||
else: print(' or', end='')
|
else: print(' or', end='')
|
||||||
print('\t%s' % (line))
|
print('\t{}'.format(line))
|
||||||
print('\n\033[1mCONFIGURATIONS:\033[21m\n')
|
|
||||||
|
print()
|
||||||
|
|
||||||
|
def help(self):
|
||||||
|
'''
|
||||||
|
Prints a colourful help message.
|
||||||
|
'''
|
||||||
|
|
||||||
|
# The usage should be terse so this header is only included in the help command.
|
||||||
|
print('\033[1m{}\033[21m - {}\n'.format(self.__program, self.__description))
|
||||||
|
|
||||||
|
self.usage()
|
||||||
|
|
||||||
|
print('\033[1mCONFIGURATIONS:\033[21m\n')
|
||||||
for opt in self.__arguments:
|
for opt in self.__arguments:
|
||||||
(opt_type, opt_alts, opt_arg, opt_help) = opt[0:4]
|
(opt_type, opt_alts, opt_arg, opt_help) = opt[0:4]
|
||||||
if opt_help is not None:
|
if opt_help is not None:
|
||||||
|
|
Loading…
Reference in a new issue