kiwi-el8/kiwi/cli.py
Marcus Schäfer 40e6308aa9 Port application from python 2.7 to 3.4
For new applications like this kiwi version and its use cases
it is better to base it on a more recent python version
2016-02-17 22:38:38 +01:00

176 lines
5.6 KiB
Python

# Copyright (c) 2015 SUSE Linux GmbH. All rights reserved.
#
# This file is part of kiwi.
#
# kiwi is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# kiwi 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 kiwi. If not, see <http://www.gnu.org/licenses/>
#
"""
usage: kiwi -h | --help
kiwi result <command> [<args>...]
kiwi [--profile=<name>...]
[--type=<build_type>]
[--logfile=<filename>]
[--debug]
system <command> [<args>...]
kiwi --compat <legacy_args>...
kiwi -v | --version
kiwi help
global options:
-v --version
show program version
--profile=<name>
profile name, multiple profiles can be selected by passing
this option multiple times
--type=<build_type>
image build type. If not set the default XML specified
build type will be used
--logfile=<filename>
create a log file containing all log information including
debug information even if this is was not requested by the
debug switch
--compat
support legacy kiwi commandline, e.g
kiwi --compat -- --build /my/description --type vmx -d /my/dest
--debug
print debug information
help
show manual page
"""
import sys
import glob
import re
import os
import importlib
from docopt import docopt
# project
from .exceptions import (
KiwiUnknownServiceName,
KiwiCommandNotLoaded,
KiwiLoadCommandUndefined,
KiwiCompatError
)
from .defaults import Defaults
from .version import __version__
from .help import Help
class Cli(object):
"""
Commandline interface
"""
def __init__(self):
self.all_args = docopt(
__doc__,
version='KIWI (next generation) version ' + __version__,
options_first=True
)
self.command_args = self.all_args['<args>']
self.command_loaded = None
def show_and_exit_on_help_request(self):
if self.all_args['help']:
manual = Help()
manual.show('kiwi')
sys.exit(0)
def get_servicename(self):
if self.all_args['system']:
return 'system'
elif self.all_args['result']:
return 'result'
elif self.all_args['--compat']:
return 'compat'
else:
raise KiwiUnknownServiceName(
'Unknown/Invalid Servicename'
)
def invoke_kiwicompat(self, compat_args):
kiwicompat = '/usr/bin/kiwicompat'
if not os.path.exists(kiwicompat):
raise KiwiCompatError('%s not found' % kiwicompat)
try:
os.execvp('kiwicompat', ['kiwicompat'] + compat_args)
except Exception as e:
raise KiwiCompatError(
'%s: %s' % (type(e).__name__, format(e))
)
def get_command(self):
return self.all_args['<command>']
def get_command_args(self):
return self.__load_command_args()
def get_global_args(self):
result = {}
for arg, value in list(self.all_args.items()):
if not arg == '<command>' and not arg == '<args>':
result[arg] = value
return result
def load_command(self):
command = self.get_command()
service = self.get_servicename()
if service == 'compat':
return self.invoke_kiwicompat(
self.all_args['<legacy_args>'][1:]
)
if not command:
raise KiwiLoadCommandUndefined(
'No command specified for %s service' % service
)
command_source_file = Defaults.project_file(
service + '_' + command + '_task.py'
)
if not os.path.exists(command_source_file):
from .logger import log
log.info('Did you mean')
for service_command in self.__get_command_implementations(service):
log.info('--> kiwi %s', service_command)
raise SystemExit
self.command_loaded = importlib.import_module(
'kiwi.' + service + '_' + command + '_task'
)
return self.command_loaded
def __get_command_implementations(self, service):
command_implementations = []
glob_match = Defaults.project_file('.') + '/*task.py'
for source_file in glob.iglob(glob_match):
with open(source_file, 'r') as source:
for line in source:
if re.search('usage: (.*)', line):
command_path = os.path.basename(source_file).split('_')
if command_path[0] == service:
command_path.pop()
command_implementations.append(
' '.join(command_path)
)
break
return command_implementations
def __load_command_args(self):
try:
argv = [
self.get_servicename(), self.get_command()
] + self.command_args
return docopt(self.command_loaded.__doc__, argv=argv)
except Exception:
raise KiwiCommandNotLoaded(
'%s command not loaded' % self.get_command()
)