mirror of
https://github.com/erkin/ponysay.git
synced 2024-11-21 12:07:59 +01:00
dd922c09bb
fish completions should never be installed to share/fish/completions/ as that directory is reserved exclusively for completions shipped as part of the fish source code. Use the same vendor_completions.d/ directory which the default fish configuration uses.
1239 lines
59 KiB
Python
Executable file
1239 lines
59 KiB
Python
Executable file
#!/usr/bin/env python3
|
|
# -*- coding: utf-8 -*-
|
|
|
|
import os
|
|
import shutil
|
|
import sys
|
|
from zipfile import ZipFile
|
|
from subprocess import Popen, PIPE
|
|
|
|
PONYSAY_VERSION = '3.0.4'
|
|
|
|
project_dir = os.path.dirname(__file__)
|
|
|
|
manpages = [('en', 'English'), # must be first
|
|
('es', 'Spanish'),
|
|
('sv', 'Swedish'),
|
|
('tr', 'Turkish')]
|
|
|
|
sharedirs = [('ponies', 'xterm ponies', 'PONYDIR', True), # must be first
|
|
('ttyponies', 'tty ponies', 'TTYPONYDIR', True),
|
|
('extraponies', 'extra xterm ponies', 'XPONYDIR', True),
|
|
('extrattyponies', 'extra tty ponies', 'XTTYPONYDIR', True),
|
|
('quotes', 'pony quotes', 'QUOTEDIR', False),
|
|
('balloons', 'balloon styles', 'BALLOONDIR', False)]
|
|
|
|
sharefiles = [('ucs', 'ucsmap')]
|
|
|
|
commands = ['ponysay', 'ponythink', 'ponysay-tool']
|
|
|
|
shells = [('bash', '/usr/share/bash-completion/completions/ponysay', 'GNU Bash'),
|
|
('fish', '/usr/share/fish/vendor_completions.d/ponysay.fish', 'Friendly interactive shell'),
|
|
('zsh', '/usr/share/zsh/site-functions/_ponysay', 'zsh')]
|
|
|
|
mansections = [('ponysay', '6'),
|
|
('cowsay', '1'),
|
|
('fortune', '6'),
|
|
('ponysay-tool', '6')]
|
|
|
|
miscfiles = [('COPYING', '/usr/share/licenses/ponysay/COPYING'),
|
|
('LICENSE', '/usr/share/licenses/ponysay/LICENSE'),
|
|
('CREDITS', '/usr/share/licenses/ponysay/CREDITS')]
|
|
|
|
ponysaysrc = [i for i in os.listdir(os.path.join(project_dir, 'src')) if i.endswith('.py') and not i.startswith('.')]
|
|
|
|
COPY = 'copy'
|
|
HARD = 'hard'
|
|
SYMBOLIC = 'symbolic'
|
|
|
|
class Setup():
|
|
def __init__(self):
|
|
usage_script = '\033[34;1msetup.py\033[21;39m'
|
|
usage_help = '(--version | --help)'
|
|
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 = usage.replace('\033[', '\0')
|
|
for sym in ('[', ']', '(', ')', '|', '...'):
|
|
usage = usage.replace(sym, '\033[2m' + sym + '\033[22m')
|
|
usage = usage.replace('\0', '\033[')
|
|
|
|
opts = ArgParser(program = 'setup.py',
|
|
description = 'installer for ponysay',
|
|
usage = usage)
|
|
|
|
opts.add_argumentless(alternatives = ['--help'])
|
|
opts.add_argumentless(alternatives = ['--version'])
|
|
opts.add_argumented (alternatives = ['---DESTDIR'], arg="DESTDIR")
|
|
opts.add_argumented (alternatives = ['---PREFIX'], arg="PREFIX")
|
|
|
|
opts.add_argumentless(help = 'Install everything that is not explicitly excluded',
|
|
alternatives = ['--everything', '--with-everything'])
|
|
|
|
opts.add_argumentless(help = 'Install only the essentials\nNote that this can vary depending on the version',
|
|
alternatives = ['--minimal'])
|
|
|
|
opts.add_argumentless(help = 'Install nothing (except legal documents) that is not explicitly included',
|
|
alternatives = ['--nothing', '--with-nothing'])
|
|
|
|
for command in commands:
|
|
opts.add_argumentless(help = 'Do not install the %s command' % (command),
|
|
alternatives = ['--without-' + command, '--without-' + command + '-command'])
|
|
|
|
opts.add_argumented (help = 'Install the %s command, and set file name\nDefault = /usr/bin/%s' % (command, command),
|
|
alternatives = ['--with-' + command, '--with-' + command + '-command'], arg='EXEC')
|
|
|
|
opts.add_argumentless(help = 'Do not install a user shared cache',
|
|
alternatives = ['--without-shared-cache'])
|
|
|
|
opts.add_argumented (help = 'Install a user shared cache at CACHEDIR\nDefault = /var/cache/ponysay',
|
|
alternatives = [ '--with-shared-cache'], arg='CACHEDIR')
|
|
|
|
for shell in shells:
|
|
opts.add_argumentless(help = 'Do not install completion for ' + shell[2],
|
|
alternatives = ['--without-' + shell[0], '--without-' + shell[0] + '-completion'])
|
|
|
|
opts.add_argumented (help = 'Set file name for the completion for ponysay in' + shell[2],
|
|
alternatives = ['--with-' + shell[0], '--with-' + shell[0] + '-completion'], arg='PONYSAY_%s_FILE' % (shell[0].upper()))
|
|
|
|
opts.add_argumentless(help = 'Only install explicitly included shell completions',
|
|
alternatives = ['--without-shell', '--without-shell-completion'])
|
|
|
|
opts.add_argumented (help = 'Set share/ directory used for shell completions\nDefault = $SHAREDIR',
|
|
alternatives = ['--with-shell', '--with-shell-completion'], arg='SHAREDIR')
|
|
|
|
opts.add_argumentless(help = 'Do not install PDF manual\nDefault',
|
|
alternatives = ['--without-pdf', '--without-pdf-manual'])
|
|
|
|
opts.add_argumented (help = 'Set directory for PDF manual\nDefault = $PREFIX/doc',
|
|
alternatives = ['--with-pdf', '--with-pdf-manual'], arg='DOCDIR')
|
|
|
|
opts.add_argumentless(help = 'Do not compress PDF manual\nDefault',
|
|
alternatives = ['--without-pdf-compression', '--without-pdf-manual-compression'])
|
|
|
|
opts.add_argumented (help = 'Select compression for PDF manual\nDefault = gz, xz is also recognised',
|
|
alternatives = ['--with-pdf-compression', '--with-pdf-manual-compression'], arg='COMPRESSION')
|
|
|
|
opts.add_argumentless(help = 'Do not install info manual',
|
|
alternatives = ['--without-info', '--without-info-manual'])
|
|
|
|
opts.add_argumented (help = 'Set directory for info manual\nDefault = $SHARE/info',
|
|
alternatives = ['--with-info', '--with-info-manual'], arg='INFODIR')
|
|
|
|
opts.add_argumentless(help = 'Do not use install-info when installing info manual',
|
|
alternatives = ['--without-info-install', '--without-info-manual-install'])
|
|
|
|
opts.add_argumented (help = 'Use install-info when installing info manual, and set description\nDefault',
|
|
alternatives = ['--with-info-install', '--with-info-manual-install'], arg='DESCRIPTION')
|
|
|
|
opts.add_argumentless(help = 'Do not compress info manual',
|
|
alternatives = ['--without-info-compression', '--without-info-manual-compression'])
|
|
|
|
opts.add_argumented (help = 'Select compression for info manual\nDefault = gz, xz is also recognised',
|
|
alternatives = ['--with-info-compression', '--with-info-manual-compression'], arg='COMPRESSION')
|
|
|
|
for man in manpages:
|
|
opts.add_argumentless(help = 'Do not install %s manpage manual' % (man[1]),
|
|
alternatives = ['--without-man-%s' % (man[0]), '--without-manpage-%s' % (man[0]), '--without-man-manual-%s' % (man[0]),
|
|
'--without-%s-man' % (man[0]), '--without-%s-manpage' % (man[0]), '--without-%s-man-manual' % (man[0])])
|
|
|
|
opts.add_argumented (help = 'Set directory for %s manpage\nDefault = $SHARE/man' % (man[1]),
|
|
alternatives = ['--with-man-%s' % (man[0]), '--with-manpage-%s' % (man[0]), '--with-man-manual-%s' % (man[0]),
|
|
'--with-%s-man' % (man[0]), '--with-%s-manpage' % (man[0]), '--with-%s-man-manual' % (man[0])], arg='MANDIR')
|
|
|
|
opts.add_argumentless(help = 'Do not install any manpages',
|
|
alternatives = ['--without-man', '--without-manpage', '--without-man-manual'])
|
|
|
|
opts.add_argumented (help = 'Set directory for all man pages\nDefault = $SHARE/man',
|
|
alternatives = ['--with-man', '--with-manpage', '--with-man-manual'], arg='MANDIR')
|
|
|
|
for man in manpages:
|
|
opts.add_argumentless(help = 'Do not compress %s manpage' % (man[1]),
|
|
alternatives = ['--without-man-%s-compression' % (man[0]), '--without-manpage-%s-compression' % (man[0]), '--without-man-manual-%s-compression' % (man[0]),
|
|
'--without-%s-man-compression' % (man[0]), '--without-%s-manpage-compression' % (man[0]), '--without-%s-man-manual-compression' % (man[0])])
|
|
|
|
opts.add_argumented (help = 'Select compression for %s manpage\nDefault = gz, xz is also recognised' % (man[1]),
|
|
alternatives = ['--with-man-%s-compression' % (man[0]), '--with-manpage-%s-compression' % (man[0]), '--with-man-manual-%s-compression' % (man[0]),
|
|
'--with-%s-man-compression' % (man[0]), '--with-%s-manpage-compression' % (man[0]), '--with-%s-man-manual-compression' % (man[0])],
|
|
arg='COMPRESSION')
|
|
|
|
opts.add_argumentless(help = 'Do not compress any installed manpage',
|
|
alternatives = ['--without-man-compression', '--without-manpage-compression', '--without-man-manual-compression'])
|
|
|
|
opts.add_argumented (help = 'Select compression for installed manpages\nDefault = gz, xz is also recognised',
|
|
alternatives = ['--with-man-compression', '--with-manpage-compression', '--with-man-manual-compression'], arg='COMPRESSION')
|
|
|
|
for man in mansections:
|
|
opts.add_argumented (help = 'Change the section for the %s manpage\nDefault = %s' % man,
|
|
alternatives = ['--man-section-%s' % (man[0]), '--%s-manpage-section' % (man[0]),
|
|
'--man-section-%s' % (man[0]), '--%s-manpage-section' % (man[0])], arg='SECTION')
|
|
|
|
for dir in sharedirs:
|
|
opts.add_argumentless(help = 'Do not install ' + dir[1],
|
|
alternatives = ['--without-' + dir[0]])
|
|
|
|
opts.add_argumentless(help = 'Install %s\nDefault' % dir[1],
|
|
alternatives = [ '--with-' + dir[0]])
|
|
|
|
opts.add_argumentless(help = 'Do not install UCS pony name map',
|
|
alternatives = ['--without-ucs', '--without-ucs-names'])
|
|
|
|
opts.add_argumentless(help = 'Install UCS pony name map\nDefault',
|
|
alternatives = ['--with-ucs', '--with-ucs-names'])
|
|
|
|
opts.add_argumentless(help = 'Let the installer set the env name for python in ponysay\nDefault',
|
|
alternatives = ['--without-custom-env-python'])
|
|
|
|
opts.add_argumented (help = 'Set the env name for python in ponysay',
|
|
alternatives = ['--with-custom-env-python'], arg='PYTHON')
|
|
|
|
opts.add_argumented (help = 'Set a prefix to all implicit directories\nDefault = /usr',
|
|
alternatives = ['--prefix'], arg='PREFIX')
|
|
|
|
opts.add_argumentless(help = 'Change all implicit configurations to fit local user a installation for the current user',
|
|
alternatives = ['--private'])
|
|
|
|
opts.add_argumentless(help = 'Change all implicit directories to fit installation to /opt',
|
|
alternatives = ['--opt'])
|
|
|
|
opts.add_argumented (help = 'Set the system\'s directory for command executables\nDefault = $PREFIX/bin',
|
|
alternatives = ['--bin-dir', '--bindir'], arg='BINDIR')
|
|
|
|
opts.add_argumented (alternatives = ['--sbin-dir', '--sbindir'], arg='SBINDIR')
|
|
|
|
opts.add_argumented (help = 'Set the system\'s directory for non-executable libraries\nDefault = $PREFIX/lib/ponysay\nNot used.',
|
|
alternatives = ['--lib-dir', '--libdir'], arg='LIBDIR')
|
|
|
|
opts.add_argumented (help = 'Set the system\'s directory for non-command executables\nDefault = $PREFIX/libexec/ponysay\nNot used.',
|
|
alternatives = ['--libexec-dir', '--libexecdir'], arg='LIBEXECDIR')
|
|
|
|
opts.add_argumented (help = 'Set the system\'s directory for resource files\nDefault = $PREFIX/share',
|
|
alternatives = ['--share-dir', '--sharedir'], arg='SHAREDIR')
|
|
|
|
opts.add_argumented (help = 'Set the system\'s local specific configuration directory\nDefault = /etc',
|
|
alternatives = ['--sysconf-dir', '--sysconfdir'], arg='SYSCONFDIR')
|
|
|
|
opts.add_argumented (help = 'Set the system\'s directory for cache directories\nDefault = /var/cache',
|
|
alternatives = ['--cache-dir', '--cachedir'], arg='CACHEDIR')
|
|
|
|
opts.add_argumented (help = 'Set off environment for installation\nEmpty by default',
|
|
alternatives = ['--dest-dir', '--destdir'], arg='DESTDIR')
|
|
|
|
opts.add_argumented (help = 'Set how to link identical files\nDefault = symbolic, copy and hard are also recognised',
|
|
alternatives = ['--linking'], arg='TYPE')
|
|
|
|
opts.add_argumented (help = 'Install all ponies or only the completely free ponies\nThis option is manditory, use strict, full, true or yes ' +
|
|
'for only free ponies,\nand partial, sloppy, false or no for all ponies',
|
|
alternatives = ['--freedom'], arg='FREEDOM')
|
|
|
|
opts.parse()
|
|
|
|
self.linking = SYMBOLIC
|
|
if opts.opts['--linking'] is not None:
|
|
self.linking = opts.opts['--linking'][0]
|
|
|
|
self.free = None
|
|
if opts.opts['--freedom'] is not None:
|
|
if opts.opts['--freedom'][0].lower() in ('strict', 'full', 'true', 'yes'):
|
|
self.free = True
|
|
elif opts.opts['--freedom'][0].lower() in ('partial', 'sloppy', 'false', 'no'):
|
|
self.free = False
|
|
def checkFreedom():
|
|
if self.free is None:
|
|
print()
|
|
print('You need to select your freedom, add --freedom=strict or --freedom=partial.')
|
|
print()
|
|
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()
|
|
print()
|
|
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):
|
|
destdir = opts.opts['---DESTDIR'][0]
|
|
if len(destdir) > 0:
|
|
opts.opts['--dest-dir'] = [destdir]
|
|
|
|
if (opts.opts['---PREFIX'] is not None) and (opts.opts['--prefix'] is None):
|
|
prefix = opts.opts['---PREFIX'][0]
|
|
if len(prefix) > 0:
|
|
opts.opts['--prefix'] = [prefix]
|
|
|
|
if opts.opts['--help'] is not None:
|
|
opts.help()
|
|
elif opts.opts['--version'] is not None:
|
|
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:
|
|
method = opts.files[0]
|
|
if method == 'clean': self.clean()
|
|
elif method == 'clean-old': self.cleanOld()
|
|
else:
|
|
conf = self.configure(opts.opts)
|
|
|
|
if method == 'build':
|
|
checkFreedom()
|
|
setup_config()
|
|
self.build(conf)
|
|
|
|
elif method == 'prebuilt':
|
|
checkFreedom()
|
|
setup_config()
|
|
self.applyDestDir(conf)
|
|
self.install(conf)
|
|
|
|
elif method == 'install':
|
|
checkFreedom()
|
|
setup_config()
|
|
self.build(conf)
|
|
self.applyDestDir(conf)
|
|
self.install(conf)
|
|
self.clean()
|
|
|
|
elif method == 'uninstall':
|
|
setup_config()
|
|
self.uninstall(conf)
|
|
|
|
elif method == 'uninstall-old':
|
|
setup_config()
|
|
self.uninstallOld(conf)
|
|
|
|
elif method == 'view':
|
|
setup_config()
|
|
else:
|
|
opts.print_fatal('Unknown command: {}', method)
|
|
opts.usage()
|
|
|
|
def viewconf(self, conf):
|
|
'''
|
|
Display configurations
|
|
'''
|
|
|
|
RED = '\033[31m%s\033[39m'
|
|
GREEN = '%s\033[32m%s\033[39m'
|
|
YELLOW = '\033[33m%s\033[39m'
|
|
|
|
for command in commands:
|
|
if conf[command] is not None: print(GREEN % ('Installing command ' + command + ' as ', conf[command]))
|
|
else: print(RED % ('Skipping installion of command ' + command))
|
|
if conf['shared-cache'] is not None: print(GREEN % ('Installing shared cache at ', conf['shared-cache']))
|
|
else: print(RED % ('Skipping installation of shared cache'))
|
|
for shell in [item[0] for item in shells]:
|
|
if conf[shell] is not None: print(GREEN % ('Installing auto-completion for ' + shell + ' as ', conf[shell]))
|
|
else: print(RED % ('Skipping installation of auto-completion for ' + shell))
|
|
if conf['pdf'] is not None: print(GREEN % ('Installing PDF manual to ', conf['pdf']))
|
|
else: print(RED % ('Skipping installation of PDF manual'))
|
|
if conf['pdf-compression'] is not None: print(GREEN % ('Compressing PDF manual with ', conf['pdf-compression']))
|
|
else: print(RED % ('Skipping compression of PDF manual'))
|
|
if conf['info'] is not None: print(GREEN % ('Installing info manual to ', conf['info']))
|
|
else: print(RED % ('Skipping installation of info manual'))
|
|
if conf['info-install'] is not None: print(GREEN % ('Installing info manual with install-info with description: ', conf['info-install']))
|
|
else: print(RED % ('Skipping installation of info manual with install-info'))
|
|
if conf['info-compression'] is not None: print(GREEN % ('Compressing info manual with ', conf['info-compression']))
|
|
else: print(RED % ('Skipping compression of info manual'))
|
|
for man in manpages:
|
|
key = 'man-' + man[0]
|
|
if conf[key] is not None: print(GREEN % ('Installing ' + man[1] + ' manpage to ', conf[key]))
|
|
else: print(RED % ('Skipping installation of ' + man[1] + ' manpage'))
|
|
key += '-compression'
|
|
if conf[key] is not None: print(GREEN % ('Compressing ' + man[1] + ' manpage with ', conf[key]))
|
|
else: print(RED % ('Skipping compression of ' + man[1] + ' manpage'))
|
|
for man in mansections: print(GREEN % ('References to manpage for ' + man[0] + ' points to section ', conf['man-section-' + man[0]]))
|
|
for dir in sharedirs:
|
|
if conf[dir[0]] is not None: print(GREEN % ('Installing ' + dir[1] + ' to ', conf['share-dir'] + '/' + dir[0]))
|
|
else: print(RED % ('Skipping installation of ' + dir[1]))
|
|
for file in sharefiles:
|
|
if conf[file[0]] is not None: print(GREEN % ('Installing ' + file[1] + ' as ', conf['share-dir'] + '/' + file[0]))
|
|
else: print(RED % ('Skipping installation of ' + file[1]))
|
|
if conf['custom-env-python'] is not None: print(GREEN % ('Using custom env reference in python script shebang: ', conf['custom-env-python']))
|
|
else: print(YELLOW % ('Looking for best env reference in python script shebang'))
|
|
for miscfile in miscfiles: print(GREEN % ('Installing ' + miscfile[0] + ' to ', conf[miscfile[0]]))
|
|
print('Using system configuration directory: ' + conf['sysconf-dir'])
|
|
print('Prefered linking style: ' + self.linking)
|
|
print('Using umask: 022 (only owner can do modifications)')
|
|
if self.free is None: print(YELLOW % ('\033[01m--freedom is manditory and has not be specified\033[21m'))
|
|
elif self.free: print(GREEN % ('', 'Installing only fully free parts of the package'))
|
|
else: print(RED % ('Installing \033[1mnot\033[21m only fully free parts of the package'))
|
|
|
|
print()
|
|
|
|
def build(self, conf):
|
|
'''
|
|
Compile ponysay
|
|
'''
|
|
|
|
print('\033[1;34m::\033[39mCompiling...\033[21m')
|
|
|
|
def compressCommand(ext):
|
|
if ext == 'gz': return 'gzip -9 -f'
|
|
if ext == 'xz': return 'xz -9e -f'
|
|
|
|
def compress(source, destination, ext):
|
|
print('%s < %s > %s' % (compressCommand(ext), source, destination))
|
|
(fileout, filein) = (None, None)
|
|
try:
|
|
fileout = open(destination, 'w+')
|
|
filein = open(source, 'r')
|
|
Popen(compressCommand(ext).split(' '), stdout=fileout, stdin=filein).communicate()
|
|
finally:
|
|
if fileout is not None: fileout.close()
|
|
if filein is not None: filein .close()
|
|
|
|
(fileout, filein) = (None, None)
|
|
|
|
env = conf['custom-env-python']
|
|
if env is None:
|
|
try:
|
|
(out, err) = Popen(['env', 'python', '--version'], stdout=PIPE, stderr=PIPE).communicate()
|
|
out = out.decode('utf8', 'replace') + err.decode('utf8', 'replace')
|
|
out = out.replace('\n', '')
|
|
env = out.split(' ')[1].split('.')[0]
|
|
if int(env) < 3: env = 'python3'
|
|
else: env = 'python'
|
|
except:
|
|
env = 'python3'
|
|
mane = False
|
|
for command in commands:
|
|
if conf[command] is not None:
|
|
mane = True
|
|
break
|
|
if mane:
|
|
for src in ponysaysrc:
|
|
try:
|
|
fileout = open('src/%s.install' % src, 'wb+')
|
|
filein = open('src/%s' % src, 'rb')
|
|
data = filein.read().decode('utf-8', 'replace')
|
|
|
|
if '#!/usr/bin/env python3' in data:
|
|
data = data.replace('#!/usr/bin/env python3', '#!/usr/bin/env ' + env)
|
|
else:
|
|
data = data.replace('#!/usr/bin/env python', '#!/usr/bin/env ' + env)
|
|
data = data.replace('/usr/share/ponysay/', conf['share-dir'] + ('' if conf['share-dir'].endswith('/') else '/'))
|
|
data = data.replace('/etc/', conf['sysconf-dir'] + ('' if conf['sysconf-dir'].endswith('/') else '/'))
|
|
data = data.replace('\nVERSION = \'dev\'', '\nVERSION = \'%s\'' % (PONYSAY_VERSION))
|
|
|
|
fileout.write(data.encode('utf-8'))
|
|
finally:
|
|
if fileout is not None: fileout.close()
|
|
if filein is not None: filein .close()
|
|
print('Creating uncompressed zip file ponysay.zip with files from src: ' + ' '.join(ponysaysrc))
|
|
myzip = None
|
|
try:
|
|
myzip = ZipFile('ponysay.zip', 'w')
|
|
for src in ponysaysrc:
|
|
myzip.write('src/%s.install' % src, src)
|
|
finally:
|
|
myzip.close()
|
|
os.chmod('ponysay.zip', 0o755)
|
|
try:
|
|
fileout = open('ponysay.install', 'wb+')
|
|
filein = open('ponysay.zip', 'rb')
|
|
fileout.write(('#!/usr/bin/env %s\n' % env).encode('utf-8'))
|
|
fileout.write(filein.read())
|
|
finally:
|
|
if fileout is not None: fileout.close()
|
|
if filein is not None: filein .close()
|
|
|
|
for man in manpages:
|
|
key = 'man-' + man[0]
|
|
section = conf['man-section-ponysay']
|
|
if man is manpages[0]: lang = ''
|
|
else: lang = '.' + man[0]
|
|
if conf[key] is not None:
|
|
src = 'manuals/manpage' + lang + '.6'
|
|
dest = src + '.install'
|
|
(fileout, filein) = (None, None)
|
|
try:
|
|
fileout = open(dest, 'wb+')
|
|
filein = open(src, 'rb')
|
|
data = filein.read().decode('utf-8', 'replace')
|
|
|
|
data = data.replace('\n.TH PONYSAY 0', '\n.TH PONYSAY ' + conf['man-section-ponysay'])
|
|
for section in [item[0] for item in mansections]:
|
|
data = data.replace('\n.BR %s (0)' % (section), '\n.BR %s (%s)' % (section, conf['man-section-' + section]))
|
|
|
|
fileout.write(data.encode('utf-8'))
|
|
finally:
|
|
if fileout is not None: fileout.close()
|
|
if filein is not None: filein .close()
|
|
src = dest
|
|
ext = conf[key + '-compression']
|
|
if ext is not None:
|
|
dest = 'manuals/manpage' + lang + '.6.' + ext
|
|
compress(src, dest, ext)
|
|
|
|
if conf['info'] is not None:
|
|
print('makeinfo manuals/ponysay.texinfo')
|
|
os.system('makeinfo manuals/ponysay.texinfo')
|
|
ext = conf['info-compression']
|
|
if ext is not None:
|
|
compress('ponysay.info', 'ponysay.info.' + ext, ext)
|
|
|
|
if conf['pdf-compression'] is not None:
|
|
ext = conf['pdf-compression']
|
|
if ext is not None:
|
|
compress('ponysay.pdf', 'ponysay.pdf.' + ext, ext)
|
|
|
|
for command in commands:
|
|
source = 'completion/ponysay'
|
|
sourceed = 'completion/ponysay.%s' % (command)
|
|
try:
|
|
fileout = open(sourceed, 'wb+')
|
|
filein = open(source, 'rb')
|
|
data = filein.read().decode('utf-8', 'replace')
|
|
|
|
if data.startswith('(ponysay\n'):
|
|
data = ('(%s ' % command) + data[len('(ponysay\n'):]
|
|
elif data.startswith('(ponysay '):
|
|
data = ('(%s ' % command) + data[len('(ponysay '):]
|
|
elif '\n(ponysay\n' in data:
|
|
edpos = data.find('\n(ponysay\n')
|
|
data = data[:edpos] + ('\n(%s\n' % command) + data[edpas + len('\n(ponysay\n'):]
|
|
elif '\n(ponysay ' in data:
|
|
data = data[:edpos] + ('\n(%s ' % command) + data[edpas + len('\n(ponysay '):]
|
|
else:
|
|
raise Exception('File %s does not look like expected' % source)
|
|
|
|
fileout.write(data.encode('utf-8'))
|
|
finally:
|
|
if fileout is not None: fileout.close()
|
|
if filein is not None: filein .close()
|
|
|
|
for shell in [item[0] for item in shells]:
|
|
if conf[shell] is not None:
|
|
for command in commands:
|
|
sourceed = 'completion/ponysay.%s' % (command)
|
|
generated = 'completion/%s-completion.%s' % (shell, command)
|
|
generatorcmd = './completion/auto-auto-complete.py %s --output %s --source %s' % (shell, generated, sourceed)
|
|
Popen(generatorcmd.split(' ')).communicate()
|
|
if conf[command] is not None:
|
|
dest = generated + '.install'
|
|
(fileout, filein) = (None, None)
|
|
try:
|
|
fileout = open(dest, 'wb+')
|
|
filein = open(generated, 'rb')
|
|
data = filein.read().decode('utf-8', 'replace')
|
|
|
|
data = data.replace('/usr/bin/ponysay', conf[command])
|
|
data = data.replace('/ponysay', '\0')
|
|
data = data.replace('ponysay', command)
|
|
data = data.replace('/usr/share/ponysay/', conf['share-dir'] if conf['share-dir'].endswith('/') else (conf['share-dir'] + '/'))
|
|
data = data.replace('\0', '/ponysay')
|
|
|
|
fileout.write(data.encode('utf-8'))
|
|
finally:
|
|
if fileout is not None: fileout.close()
|
|
if filein is not None: filein .close()
|
|
|
|
if conf['quotes'] is not None:
|
|
self.removeLists([], ['quotes'])
|
|
os.mkdir('quotes')
|
|
ponymap = None
|
|
try:
|
|
ponymap = open('ponyquotes/ponies', 'rb')
|
|
ponies = [line for line in ponymap.read().decode('utf-8', 'replace').split('\n')]
|
|
for _ponies in ponies:
|
|
for pony in _ponies.split('+'):
|
|
if len(pony) > 0:
|
|
print('Generating quote files for \033[34m' + pony + '\033[39m')
|
|
for file in os.listdir('ponyquotes'):
|
|
if file.startswith(pony + '.'):
|
|
if os.path.isfile('ponyquotes/' + file):
|
|
shutil.copy('ponyquotes/' + file, 'quotes/' + _ponies + file[file.find('.'):])
|
|
finally:
|
|
if ponymap is not None:
|
|
ponymap.close()
|
|
|
|
for (sharedir, hasponies) in [(sharedir[0], sharedir[3]) for sharedir in sharedirs]:
|
|
if hasponies and os.path.isdir(sharedir):
|
|
for toolcommand in ('--dimensions', '--metadata'):
|
|
if not self.free:
|
|
print('%s, %s, %s' % ('./src/ponysaytool.py', toolcommand, sharedir))
|
|
Popen(['./src/ponysaytool.py', toolcommand, sharedir], stdin=PIPE, stdout=PIPE, stderr=PIPE).communicate()
|
|
else:
|
|
params = ['./src/ponysaytool.py', toolcommand, sharedir, '--']
|
|
for sharefile in os.listdir(sharedir):
|
|
if sharefile.endswith('.pony') and (sharefile != '.pony'):
|
|
if not Setup.validateFreedom(sharedir + '/' + sharefile):
|
|
print('Skipping metadata correction for %s/%s, did not pass validation process made by setup settings' % (sharedir, sharefile))
|
|
else:
|
|
params.append(sharefile)
|
|
print('%s, %s, %s (with files)' % ('./src/ponysaytool.py', toolcommand, sharedir))
|
|
Popen(params, stdin=PIPE, stdout=PIPE, stderr=PIPE).communicate()
|
|
|
|
print()
|
|
|
|
def install(self, conf):
|
|
'''
|
|
Install compiled ponysay
|
|
'''
|
|
|
|
print('\033[1;34m::\033[39mInstalling...\033[21m')
|
|
|
|
dests = []
|
|
for command in commands:
|
|
if conf[command] is not None:
|
|
dests.append(conf[command])
|
|
if len(dests) > 0:
|
|
self.cp(False, 'ponysay.install', dests)
|
|
print('Setting mode for ponysay.install copies to 755')
|
|
if self.linking == COPY:
|
|
for dest in dests:
|
|
os.chmod(dest, 0o755)
|
|
else:
|
|
os.chmod(dests[0], 0o755)
|
|
if conf['shared-cache'] is not None:
|
|
dir = conf['shared-cache']
|
|
if not os.path.exists(dir):
|
|
pdir = dir[:dir.rfind('/') + 1]
|
|
if not os.path.exists(pdir):
|
|
print('Creating intermediate-level directories needed for ' + dir)
|
|
os.makedirs(pdir)
|
|
print('Creating directory ' + dir)
|
|
os.mkdir(dir)
|
|
print('Setting permission mode mask for ' + dir + ' to 7777')
|
|
Popen('chmod -R 7777 -- \'' + dir.replace('\'', '\'\\\'\'') + '\'', shell=True).wait()
|
|
print('Setting group for ' + dir + ' users')
|
|
Popen('chown -R :users -- \'' + dir.replace('\'', '\'\\\'\'') + '\'', shell=True).wait()
|
|
for shell in [item[0] for item in shells]:
|
|
if conf[shell] is not None:
|
|
for command in commands:
|
|
if conf[command] is not None:
|
|
src = 'completion/%s-completion.%s.install' % (shell, command)
|
|
dest = os.path.join(
|
|
os.path.dirname(conf[shell]),
|
|
os.path.basename(conf[shell]).replace('ponysay', command))
|
|
self.cp(False, src, [dest])
|
|
if conf['pdf'] is not None:
|
|
src = 'ponysay.pdf' + ('' if conf['pdf-compression'] is None else '.' + conf['pdf-compression'])
|
|
dest = conf['pdf'] + '/' + src
|
|
self.cp(False, src, [dest])
|
|
if conf['info'] is not None:
|
|
installinfo = []
|
|
dests = []
|
|
ext = ('' if conf['info-compression'] is None else '.' + conf['info-compression'])
|
|
src = 'ponysay.info' + ext
|
|
for command in commands:
|
|
if conf[command] is not None:
|
|
dest = conf['info'] + '/' + command + '.info' + ext
|
|
dests.append(dest)
|
|
if conf['info-install'] is not None:
|
|
cmdarr = ['install-info', '--entry=Miscellaneous', '--description=' + conf['info-install'], '--dir-file=' + conf['info'] + '/dir', dest]
|
|
cmd = ' '.join(['\'%s\'' % (elem.replace('\'', '\'\\\'\'')) for elem in cmdarr])
|
|
installinfo.append((cmd, 'Installing info manual ' + dest + ' with install-info'))
|
|
self.cp(False, src, dests)
|
|
for pair in installinfo:
|
|
print(pair[1])
|
|
os.system(pair[0])
|
|
for man in manpages:
|
|
key = 'man-' + man[0]
|
|
section = conf['man-section-ponysay']
|
|
if man is manpages[0]: sub = 'man' + section
|
|
else: sub = man[0] + '/man' + section
|
|
if man is manpages[0]: lang = ''
|
|
else: lang = '.' + man[0]
|
|
if conf[key] is not None:
|
|
src = 'manuals/manpage' + lang + '.6.' + ('install' if conf[key + '-compression'] is None else conf[key + '-compression'])
|
|
dests = []
|
|
for command in commands:
|
|
if conf[command] is not None:
|
|
dest = '%s/%s/%s.%s%s' % (conf[key], sub, command, section, '' if conf[key + '-compression'] is None else '.' + conf[key + '-compression'])
|
|
dests.append(dest)
|
|
self.cp(False, src, dests)
|
|
ponyshare = conf['share-dir']
|
|
if not ponyshare.endswith('/'):
|
|
ponyshare += '/'
|
|
for dir in sharedirs:
|
|
if conf[dir[0]] is not None:
|
|
self.cp(True, dir[0], [ponyshare + dir[0]], Setup.validateFreedom if self.free else None)
|
|
for file in sharefiles:
|
|
if conf[file[0]] is not None:
|
|
self.cp(False, 'share/' + file[1], [ponyshare + file[0]], Setup.validateFreedom if self.free else None)
|
|
for file in miscfiles:
|
|
self.cp(False, file[0], [conf[file[0]]], Setup.validateFreedom if self.free else None)
|
|
print()
|
|
|
|
def uninstall(self, conf):
|
|
'''
|
|
Uninstall ponysay
|
|
'''
|
|
|
|
print('\033[1;34m::\033[39mUninstalling...\033[21m')
|
|
|
|
(files, dirs, infos) = ([], [], [])
|
|
|
|
for command in commands:
|
|
if conf[command] is not None:
|
|
files.append(conf[command])
|
|
if conf['shared-cache'] is not None:
|
|
dirs.append(conf['shared-cache'])
|
|
for shell in [item[0] for item in shells]:
|
|
if conf[shell] is not None:
|
|
for command in commands:
|
|
if conf[command] is not None:
|
|
files.append(conf[shell].replace('ponysay', command))
|
|
if conf['pdf'] is not None:
|
|
files.append(conf['pdf'] + '/ponysay.pdf' + ('' if conf['pdf-compression'] is None else '.' + conf['pdf-compression']))
|
|
if conf['info'] is not None:
|
|
for command in commands:
|
|
if conf[command] is not None:
|
|
file = conf['info'] + '/' + command + '.info' + ('' if conf['info-compression'] is None else '.' + conf['info-compression'])
|
|
files.append(file)
|
|
if conf['info-install'] is not None:
|
|
infos.append(file)
|
|
for man in [item[0] for item in manpages]:
|
|
key = 'man-' + man
|
|
section = conf['man-section-ponysay']
|
|
if man is manpages[0]: sub = 'man' + section
|
|
else: sub = man[0] + '/man' + section
|
|
if conf[key] is not None:
|
|
for command in commands:
|
|
if conf[command] is not None:
|
|
files.append('%s/%s/%s.%s%s' % (conf[key], sub, command, section, '' if conf[key + '-compression'] is None else '.' + conf[key + '-compression']))
|
|
ponyshare = conf['share-dir']
|
|
if not ponyshare.endswith('/'):
|
|
ponyshare += '/'
|
|
for dir in sharedirs:
|
|
if conf[dir[0]] is not None:
|
|
dirs.append(ponyshare + dir[0])
|
|
for file in sharefiles:
|
|
if conf[file[0]] is not None:
|
|
files.append(ponyshare + file[0])
|
|
for file in miscfiles:
|
|
files.append(conf[file[0]])
|
|
|
|
for info in infos:
|
|
cmdarr = ['install-info', '--delete', '--dir-file=' + conf['info'] + '/dir', info]
|
|
cmd = ' '.join(['\'%s\'' % (elem.replace('\'', '\'\\\'\'')) for elem in cmdarr])
|
|
print('Uninstalling info manual ' + info + ' with install-info')
|
|
os.system(cmd)
|
|
|
|
self.removeLists(files, dirs)
|
|
print()
|
|
|
|
def uninstallOld(self, conf):
|
|
'''
|
|
Uninstall file ponysay no longer uses
|
|
'''
|
|
|
|
print('\033[1;34m::\033[39mUninstalling old files...\033[21m')
|
|
|
|
instdir = conf['~prefix~'] + '/usr'
|
|
files = [instdir + f for f in ['bin/ponysaylist.pl', 'bin/ponysaytruncater', 'bin/ponysay.py', 'bin/ponythink.py']]
|
|
dirs = [instdir + d for d in ['lib/ponysay', 'share/ponies', 'share/ttyponies']]
|
|
#$(instdir)/lib/ponysay/truncater
|
|
#$(instdir)/lib/ponysay/list.pl
|
|
#$(instdir)/lib/ponysay/linklist.pl
|
|
#$(instdir)/lib/ponysay/pq4ps
|
|
#$(instdir)/lib/ponysay/pq4ps.pl
|
|
#$(instdir)/lib/ponysay/pq4ps-list
|
|
#$(instdir)/lib/ponysay/pq4ps-list.pl
|
|
|
|
self.removeLists(files, dirs)
|
|
print()
|
|
|
|
def clean(self):
|
|
'''
|
|
Remove compiled files
|
|
'''
|
|
|
|
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 += ['src/%s.install' % file for file in ponysaysrc]
|
|
dirs = ['quotes']
|
|
for comp in ['install', 'gz', 'xz']:
|
|
for man in manpages:
|
|
if man is manpages[0]: man = ''
|
|
else: man = '.' + man[0]
|
|
for sec in range(0, 9):
|
|
files.append('manuals/manpage%s.%s.%s' % (man, str(sec), comp))
|
|
for shell in [item[0] for item in shells]:
|
|
for command in commands:
|
|
files.append('completion/%s-completion.%s' % (shell, command))
|
|
files.append('completion/%s-completion.%s.install' % (shell, command))
|
|
for sharedir in [sharedir[0] for sharedir in sharedirs]:
|
|
for dimfile in ('widths', 'heights', 'onlyheights'):
|
|
files.append(sharedir + '/' + dimfile)
|
|
|
|
self.removeLists(files, dirs)
|
|
print()
|
|
|
|
def cleanOld(self):
|
|
'''
|
|
Remove compiled files ponysay is no longer compiling
|
|
'''
|
|
|
|
print('\033[1;34m::\033[39mCleaning old files...\033[21m')
|
|
|
|
files = ['truncater', 'ponysaytruncater', 'ponysay.py.install', 'ponysay.install~', 'ponysay.zip']
|
|
dirs = []
|
|
for shell in [item[0] for item in shells]:
|
|
files.append('completion/%s-completion.%s.install' % (shell, 'sh' if shell == 'bash' else shell))
|
|
files.append('completion/%s-completion-think.%s' % (shell, 'sh' if shell == 'bash' else shell))
|
|
for shell in [item[0] for item in shells]:
|
|
for command in commands:
|
|
files.append('completion/%s-completion.%s.%s' % (shell, 'sh' if shell == 'bash' else shell, command))
|
|
|
|
self.removeLists(files, dirs)
|
|
print()
|
|
|
|
def removeLists(self, files, dirs):
|
|
'''
|
|
Removes listed files and directories
|
|
'''
|
|
|
|
for file in files:
|
|
if os.path.isfile(file) or os.path.islink(file):
|
|
print('Unlinking file %s' % (file))
|
|
os.unlink(file)
|
|
dir = file
|
|
while True:
|
|
dir = dir[:dir.rfind('/')]
|
|
if ('/ponysay/' in (dir + '/')) and (len(os.listdir(dir)) == 0):
|
|
print('Removing newly empty directory %s' % (dir))
|
|
os.rmdir(dir)
|
|
else:
|
|
break;
|
|
for dir in dirs:
|
|
if os.path.isdir(dir) or os.path.islink(dir):
|
|
print('Cascadingly removing directory %s' % (dir))
|
|
if os.path.islink(dir): os.unlink(dir)
|
|
else: shutil.rmtree(dir)
|
|
while True:
|
|
dir = dir[:dir.rfind('/')]
|
|
if ('/ponysay/' in (dir + '/')) and (len(os.listdir(dir)) == 0):
|
|
print('Removing newly empty directory %s' % (dir))
|
|
os.rmdir(dir)
|
|
else:
|
|
break;
|
|
|
|
@staticmethod
|
|
def validateFreedom(filename):
|
|
'''
|
|
Check whether a file is fully free
|
|
'''
|
|
|
|
if not os.path.isdir(filename):
|
|
if filename.endswith('.pony') and (filename != '.pony') and not filename.endswith('/.pony'):
|
|
with open(filename, 'rb') as file:
|
|
data = file.read().decode('utf8', 'replace')
|
|
if data.startswith('$$$\n') and ('\n$$$\n' in data) and not data.startswith('$$$\n$$$\n'):
|
|
data = data[4 : data.find('\n$$$\n')].split('\n')
|
|
for line in data:
|
|
if ':' not in line:
|
|
continue
|
|
line = [item.strip() for item in line.split(':')]
|
|
if (len(line) == 2) and (line[0] == 'FREE'):
|
|
return line[1].lower() == 'yes'
|
|
return False
|
|
return True
|
|
|
|
def cp(self, recursive, source, destinations, validatehook = None):
|
|
'''
|
|
Copys a files or directory to multiple destinations
|
|
'''
|
|
|
|
if validatehook is not None:
|
|
if not validatehook(source):
|
|
print('Ignoring installation of file %s (did not pass validation process made by setup settings)' % source)
|
|
return
|
|
if os.path.islink(source) and (self.linking != COPY) and os.path.isdir(os.path.realpath(source)):
|
|
target = os.readlink(source)
|
|
for dest in destinations:
|
|
print('Creating symbolic link %s with target directory %s' % (dest, target))
|
|
if os.path.exists(dest):
|
|
self.removeLists([], [dest])
|
|
self.symlink(target, dest)
|
|
if os.path.islink(source) and (self.linking != COPY) and os.path.isfile(os.path.realpath(source)):
|
|
target = os.readlink(source)
|
|
if self.linking == HARD:
|
|
for dest in destinations:
|
|
print('Creating hard link %s with target file %s' % (dest, target))
|
|
if os.path.exists(dest):
|
|
self.removeLists([], [dest])
|
|
mytarget = os.path.abspath(os.path.join(os.path.dirname(dest), target))
|
|
if os.path.exists(mytarget):
|
|
os.link(mytarget, dest)
|
|
else:
|
|
print('\033[31mTarget did not exists, using symlink instead\033[39m')
|
|
self.symlink(target, dest)
|
|
else:
|
|
for dest in destinations:
|
|
print('Creating symbolic link %s with target file %s' % (dest, target))
|
|
if os.path.exists(dest):
|
|
self.removeLists([], [dest])
|
|
self.symlink(target, dest)
|
|
for dest in destinations:
|
|
dir = dest[:dest.rfind('/') + 1]
|
|
if not os.path.exists(dir):
|
|
print('Making directory ' + dir + ' with parents')
|
|
os.makedirs(dir)
|
|
if recursive:
|
|
target = destinations[0]
|
|
for dest in destinations if self.linking == COPY else [target]:
|
|
print('Copying directory %s to %s' % (source, dest))
|
|
if not os.path.exists(dest):
|
|
os.mkdir(dest)
|
|
links = []
|
|
for file in os.listdir(source):
|
|
src = source + '/' + file
|
|
if os.path.exists(src) and os.path.islink(src):
|
|
links.append((os.path.isdir(src), src, [dest + '/' + file]))
|
|
else:
|
|
self.cp(os.path.isdir(src), src, [dest + '/' + file], validatehook)
|
|
for link in links:
|
|
self.cp(link[0], link[1], link[2], validatehook)
|
|
if self.linking != COPY:
|
|
for dest in destinations[1:]:
|
|
print('Creating symbolic link %s with target directory %s' % (dest, target))
|
|
if os.path.exists(dest):
|
|
self.removeLists([], [dest])
|
|
self.symlink(target, dest)
|
|
else:
|
|
target = destinations[0]
|
|
for dest in destinations if self.linking == COPY else [target]:
|
|
print('Copying file %s to %s' % (source, dest))
|
|
shutil.copyfile(source, dest)
|
|
if self.linking == HARD:
|
|
for dest in destinations[1:]:
|
|
print('Creating hard link %s with target file %s' % (dest, target))
|
|
if os.path.exists(dest):
|
|
os.unlink(dest)
|
|
os.link(target, dest)
|
|
elif self.linking == SYMBOLIC:
|
|
for dest in destinations[1:]:
|
|
print('Creating symbolic link %s with target file %s' % (dest, target))
|
|
if os.path.exists(dest):
|
|
os.unlink(dest)
|
|
self.symlink(target, dest)
|
|
|
|
def symlink(self, target, dest):
|
|
'''
|
|
Create a symlink with a relative path
|
|
'''
|
|
|
|
if target.startswith('./') or target.startswith('../'):
|
|
os.symlink(target, dest)
|
|
elif '/' not in target:
|
|
try:
|
|
os.symlink('./' + target, dest)
|
|
except OSError as e:
|
|
if e.errno != 17:
|
|
raise
|
|
else:
|
|
targets = target.split('/')
|
|
dests = dest.split('/')
|
|
|
|
while (len(targets) > 1) and (len(dests) > 1) and (targets[0] == dests[0]):
|
|
targets = targets[1:]
|
|
dests = dests[1:]
|
|
|
|
if (len(dests) == 1):
|
|
targets = ['.'] + targets
|
|
else:
|
|
targets = (['..'] * (len(dests) - 1)) + targets
|
|
|
|
os.symlink('/'.join(targets), dest)
|
|
|
|
def configure(self, opts):
|
|
'''
|
|
Parses configurations
|
|
'''
|
|
|
|
(defaults, conf) = ({}, {})
|
|
|
|
for command in commands:
|
|
conf[command] = '/usr/bin/' + command
|
|
conf['shared-cache'] = '/var/cache/ponysay'
|
|
for shell in shells:
|
|
conf[shell[0]] = shell[1]
|
|
conf['pdf'] = '/usr/doc'
|
|
conf['pdf-compression'] = 'gz'
|
|
conf['info'] = '/usr/share/info'
|
|
conf['info-install'] = 'My Little Ponies for your terminal'
|
|
conf['info-compression'] = 'gz'
|
|
for manpage in manpages:
|
|
conf['man-' + manpage[0]] = '/usr/share/man'
|
|
conf['man-' + manpage[0] + '-compression'] = 'gz'
|
|
conf['custom-env-python'] = 'python3'
|
|
for sharedir in sharedirs:
|
|
conf[sharedir[0]] = True
|
|
for sharefile in sharefiles:
|
|
conf[sharefile[0]] = True
|
|
for miscfile in miscfiles:
|
|
conf[miscfile[0]] = miscfile[1]
|
|
conf['sysconf-dir'] = '/etc'
|
|
conf['bin-dir'] = '/usr/bin'
|
|
conf['lib-dir'] = '/usr/lib/ponysay'
|
|
conf['libexec-dir'] = '/usr/libexec/ponysay'
|
|
conf['share-dir'] = '/usr/share'
|
|
|
|
if opts['--private'] is not None:
|
|
if opts['--prefix'] is None:
|
|
opts['--prefix'] = [os.environ['HOME'] + '/.local']
|
|
|
|
prefix = '/usr'
|
|
if opts['--prefix'] is not None:
|
|
prefix = opts['--prefix'][0]
|
|
for key in conf:
|
|
if conf[key] not in (None, False, True):
|
|
if conf[key].startswith('/usr'):
|
|
conf[key] = prefix + conf[key][4:]
|
|
conf['~prefix~'] = prefix
|
|
|
|
if opts['--opt'] is not None:
|
|
if opts['--bin-dir'] is None: opts['--bin-dir'] = ['/opt/ponysay']
|
|
if opts['--lib-dir'] is None: opts['--lib-dir'] = ['/opt/ponysay']
|
|
if opts['--libexec-dir'] is None: opts['--libexec-dir'] = ['/opt/ponysay']
|
|
if opts['--share-dir'] is None: opts['--share-dir'] = ['/opt/ponysay']
|
|
if opts['--with-shared-cache'] is None: opts['--with-shared-cache'] = ['/var/opt/ponysay/cache']
|
|
|
|
for dir in ['bin', 'lib', 'libexec', 'share']:
|
|
key = dir + '-dir'
|
|
if opts['--' + key] is not None:
|
|
conf[key] = opts['--' + key][0]
|
|
if (dir == 'share') and (opts['--opt'] is None):
|
|
conf[key] += '/ponysay'
|
|
if conf[key].startswith('usr/'):
|
|
conf[key] = prefix + conf[key][3:]
|
|
if opts['--cache-dir'] is not None:
|
|
dir = opts['--cache-dir'][0]
|
|
for key in conf:
|
|
if conf[key] not in (None, False, True):
|
|
if conf[key].startswith('/var/cache'):
|
|
conf[key] = dir + conf[key][10:]
|
|
|
|
if opts['--sysconf-dir'] is not None:
|
|
conf['sysconf-dir'] = opts['--sysconf-dir'][0]
|
|
|
|
for key in conf:
|
|
defaults[key] = conf[key]
|
|
|
|
if opts['--nothing'] is not None:
|
|
opts['--minimal'] = opts['--nothing']
|
|
|
|
for key in ['custom-env-python']:
|
|
conf[key] = None
|
|
|
|
if opts['--everything'] is None:
|
|
for key in ['pdf', 'pdf-compression']:
|
|
conf[key] = None
|
|
|
|
nomanen = opts['--minimal'] is not None
|
|
for manpage in manpages:
|
|
if (manpage is not manpages[0]) or nomanen:
|
|
for key in ['man-' + manpage[0]]:
|
|
conf[key] = None
|
|
|
|
if (opts['--private'] is not None) or (opts['--minimal'] is not None):
|
|
for key in ['info-install', 'shared-cache']:
|
|
conf[key] = None
|
|
|
|
if opts['--minimal'] is not None:
|
|
for key in ['info'] + [item[0] for item in shells]:
|
|
conf[key] = None
|
|
for sharedir in sharedirs:
|
|
if sharedir is not sharedirs[0]:
|
|
conf[sharedir[0]] = None
|
|
for sharefile in sharefiles:
|
|
conf[sharefile[0]] = None
|
|
|
|
if opts['--nothing'] is not None:
|
|
for command in commands:
|
|
conf[command] = None
|
|
conf[sharedirs[0][0]] = None
|
|
|
|
for coll in [['shell', '/usr/share', [item[0] for item in shells]],
|
|
['man', '/usr/share/man', ['man-' + item[0] for item in manpages]],
|
|
['man-compression', 'gz', ['man-' + item[0] + '-compression' for item in manpages]]
|
|
]:
|
|
if opts['--without-' + coll[0]] is not None:
|
|
for item in coll[2]:
|
|
conf[item] = None
|
|
if opts['--with-' + coll[0]] is not None:
|
|
for item in coll[2]:
|
|
defaults[item] = conf[item] = defaults[item].replace(coll[1], coll[1] if opts['--with-' + coll[0]][0] is None else opts['--with-' + coll[0]][0]);
|
|
|
|
for key in conf:
|
|
if '--with-' + key not in opts:
|
|
continue
|
|
if opts['--with-' + key] is not None:
|
|
if defaults[key] in (False, True):
|
|
conf[key] = True
|
|
else:
|
|
conf[key] = defaults[key] if opts['--with-' + key][0] is None else opts['--with-' + key][0]
|
|
if opts['--without-' + key] is not None:
|
|
conf[key] = False if defaults[key] in (False, True) else None
|
|
|
|
for mansection in mansections:
|
|
if opts['--man-section-' + mansection[0]] is not None:
|
|
conf['man-section-' + mansection[0]] = opts['--man-section-' + mansection[0]][0]
|
|
else:
|
|
conf['man-section-' + mansection[0]] = mansection[1]
|
|
|
|
self.destDir = None if opts['--dest-dir'] is None else opts['--dest-dir'][0]
|
|
|
|
return conf
|
|
|
|
def applyDestDir(self, conf):
|
|
if self.destDir is not None:
|
|
for key in conf:
|
|
if conf[key] not in (None, False, True):
|
|
if conf[key].startswith('/'):
|
|
conf[key] = self.destDir + conf[key]
|
|
|
|
def unapplyDestDir(self, conf):
|
|
if self.destDir is not None:
|
|
for key in conf:
|
|
if conf[key] not in (None, False, True):
|
|
if conf[key].startswith(self.destDir):
|
|
conf[key] = conf[key][len(self.destDir):]
|
|
|
|
|
|
ARGUMENTLESS = 0
|
|
ARGUMENTED = 1
|
|
|
|
class ArgParser():
|
|
'''
|
|
Simple argument parser, a strip down of the one in ponysay and slitly modified
|
|
'''
|
|
|
|
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.__description = description
|
|
self.__usage = usage
|
|
self.__longdescription = longdescription
|
|
self.__arguments = []
|
|
(self.opts, self.optmap) = ({}, {})
|
|
|
|
def add_argumentless(self, alternatives, help = None):
|
|
'''
|
|
Add option that takes no arguments
|
|
'''
|
|
|
|
ARGUMENTLESS
|
|
self.__arguments.append((ARGUMENTLESS, alternatives, None, help))
|
|
(stdalt, self.opts[stdalt]) = (alternatives[0], None)
|
|
for alt in alternatives: self.optmap[alt] = (stdalt, ARGUMENTLESS)
|
|
|
|
def add_argumented(self, alternatives, arg, help = None):
|
|
'''
|
|
Add option that takes one argument
|
|
'''
|
|
|
|
self.__arguments.append((ARGUMENTED, alternatives, arg, help))
|
|
(stdalt, self.opts[stdalt]) = (alternatives[0], None)
|
|
for alt in alternatives: self.optmap[alt] = (stdalt, ARGUMENTED)
|
|
|
|
def parse(self, argv = sys.argv):
|
|
'''
|
|
Parse arguments
|
|
'''
|
|
|
|
self.argcount = len(argv) - 1
|
|
self.files = []
|
|
(argqueue, optqueue, get) = ([], [], False)
|
|
|
|
for arg in argv[1:]:
|
|
if get:
|
|
get = False
|
|
if (arg is argv[-1]) or ((len(arg) > 2) and (arg[:2] in ('--', '++'))):
|
|
argqueue.append(None)
|
|
else:
|
|
argqueue.append(arg)
|
|
continue
|
|
if (len(arg) > 2) and (arg[:2] in ('--', '++')):
|
|
if (arg in self.optmap) and (self.optmap[arg][1] == ARGUMENTLESS):
|
|
optqueue.append(arg)
|
|
argqueue.append(None)
|
|
elif '=' in arg:
|
|
arg_opt = arg[:arg.index('=')]
|
|
if (arg_opt in self.optmap) and (self.optmap[arg_opt][1] == ARGUMENTED):
|
|
optqueue.append(arg_opt)
|
|
argqueue.append(arg[arg.index('=') + 1:])
|
|
else:
|
|
self.print_fatal('Unrecognized option {}. Use --help or consult the manual.', arg)
|
|
exit(-1)
|
|
elif (arg in self.optmap) and (self.optmap[arg][1] == ARGUMENTED):
|
|
optqueue.append(arg)
|
|
get = True
|
|
else:
|
|
self.print_fatal('Unrecognized option {}. Use --help or consult the manual.', arg)
|
|
exit(-1)
|
|
else:
|
|
self.files.append(arg)
|
|
|
|
(i, n) = (0, len(optqueue))
|
|
if len(argqueue) < n:
|
|
argqueue.append(None)
|
|
while i < n:
|
|
(opt, arg, i) = (optqueue[i], argqueue[i], i + 1)
|
|
opt = self.optmap[opt][0]
|
|
if (opt not in self.opts) or (self.opts[opt] is None):
|
|
self.opts[opt] = [arg]
|
|
else:
|
|
self.print_fatal('duplicate option {}', arg)
|
|
exit(-1)
|
|
|
|
def print_fatal(self, message, *args):
|
|
sys.stderr.write('{}: fatal: {}\n'.format(self.__program, message.format(*args)))
|
|
|
|
def usage(self):
|
|
'''
|
|
Print a short usage message.
|
|
'''
|
|
|
|
if self.__longdescription is not None:
|
|
print(self.__longdescription)
|
|
print()
|
|
print('\n\033[1mUSAGE:\033[21m', end='')
|
|
first = True
|
|
for line in self.__usage.split('\n'):
|
|
if first: first = False
|
|
else: print(' or', end='')
|
|
print('\t{}'.format(line))
|
|
|
|
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:
|
|
(opt_type, opt_alts, opt_arg, opt_help) = opt[0:4]
|
|
if opt_help is not None:
|
|
for opt_alt in opt_alts:
|
|
if opt_alt is opt_alts[-1]:
|
|
print('\t%s=\033[4m%s\033[24m' % (opt_alt, opt_arg) if opt_type == ARGUMENTED else '\t' + opt_alt)
|
|
else:
|
|
print('\t\033[2m' + opt_alt + '\033[22m')
|
|
first = True
|
|
for line in opt_help.split('\n'):
|
|
print(('\t\t\033[32;1m%s\033[21;39m' if first else '\t\t%s') % (line))
|
|
first = False
|
|
print()
|
|
print()
|
|
|
|
|
|
if __name__ == '__main__':
|
|
Setup()
|