Information not provided should end up as a None type in the list in any case. If an empty string was provided via e.g --add-repo source,type,, the tokenizer puts in an empty string. If the information was provided as --add-repo source,type a None type was used. The code handling the information expected a None type for not provided information, with an empty string we end up in validation code which e,g complains that an empty string can't be converted into an integer base repo priority
170 lines
4.9 KiB
Python
170 lines
4.9 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/>
|
|
#
|
|
import os
|
|
import logging
|
|
import glob
|
|
|
|
# project
|
|
from ..cli import Cli
|
|
from ..xml_state import XMLState
|
|
from ..xml_description import XMLDescription
|
|
from ..runtime_checker import RuntimeChecker
|
|
|
|
from ..exceptions import (
|
|
KiwiConfigFileNotFound
|
|
)
|
|
|
|
|
|
class CliTask(object):
|
|
"""
|
|
Base class for all task classes, loads the task and provides
|
|
the interface to the command options and the XML description
|
|
|
|
Attributes
|
|
|
|
* :attr:`cli`
|
|
Instance of Cli
|
|
|
|
* :attr:`task`
|
|
Instance of imported task class
|
|
|
|
* :attr:`command_args`
|
|
command specific docopt arguments dictionary
|
|
|
|
* :attr:`global_args`
|
|
global docopt arguments dictionary
|
|
|
|
* :attr:`runtime_checker`
|
|
Instance of RuntimeChecker
|
|
"""
|
|
def __init__(self, should_perform_task_setup=True):
|
|
from ..logger import log
|
|
|
|
self.cli = Cli()
|
|
|
|
# initialize runtime checker
|
|
self.runtime_checker = None
|
|
|
|
# help requested
|
|
self.cli.show_and_exit_on_help_request()
|
|
|
|
# load/import task module
|
|
self.task = self.cli.load_command()
|
|
|
|
# get command specific args
|
|
self.command_args = self.cli.get_command_args()
|
|
|
|
# get global args
|
|
self.global_args = self.cli.get_global_args()
|
|
|
|
if should_perform_task_setup:
|
|
# set log level
|
|
if self.global_args['--debug']:
|
|
log.setLogLevel(logging.DEBUG)
|
|
else:
|
|
log.setLogLevel(logging.INFO)
|
|
|
|
# set log file
|
|
if self.global_args['--logfile']:
|
|
log.set_logfile(
|
|
self.global_args['--logfile']
|
|
)
|
|
|
|
if self.global_args['--color-output']:
|
|
log.set_color_format()
|
|
|
|
def load_xml_description(self, description_directory):
|
|
"""
|
|
Load, upgrade, validate XML description
|
|
|
|
Attributes
|
|
|
|
* :attr:`xml_data`
|
|
instance of XML data toplevel domain (image), stateless data
|
|
|
|
* :attr:`config_file`
|
|
used config file path
|
|
|
|
* :attr:`xml_state`
|
|
Instance of XMLState, stateful data
|
|
"""
|
|
from ..logger import log
|
|
|
|
log.info('Loading XML description')
|
|
config_file = description_directory + '/config.xml'
|
|
if not os.path.exists(config_file):
|
|
# alternative config file lookup location
|
|
config_file = description_directory + '/image/config.xml'
|
|
if not os.path.exists(config_file):
|
|
# glob config file search, first match wins
|
|
glob_match = description_directory + '/*.kiwi'
|
|
for kiwi_file in glob.iglob(glob_match):
|
|
config_file = kiwi_file
|
|
break
|
|
|
|
if not os.path.exists(config_file):
|
|
raise KiwiConfigFileNotFound(
|
|
'no XML description found in %s' % description_directory
|
|
)
|
|
|
|
description = XMLDescription(
|
|
config_file
|
|
)
|
|
self.xml_data = description.load()
|
|
self.config_file = config_file.replace('//', '/')
|
|
self.xml_state = XMLState(
|
|
self.xml_data,
|
|
self.global_args['--profile'],
|
|
self.global_args['--type']
|
|
)
|
|
|
|
log.info('--> loaded %s', self.config_file)
|
|
if self.xml_state.build_type:
|
|
log.info(
|
|
'--> Selected build type: %s',
|
|
self.xml_state.get_build_type_name()
|
|
)
|
|
if self.xml_state.profiles:
|
|
log.info(
|
|
'--> Selected profiles: %s',
|
|
','.join(self.xml_state.profiles)
|
|
)
|
|
|
|
self.runtime_checker = RuntimeChecker(self.xml_state)
|
|
|
|
def quadruple_token(self, option):
|
|
"""
|
|
Helper method for commandline options of the form --option a,b,c,d
|
|
|
|
Make sure to provide a common result for option values which
|
|
separates the information in a comma separated list of values
|
|
|
|
:return: common option value representation
|
|
:rtype: string
|
|
"""
|
|
tokens = option.split(',', 3)
|
|
return [
|
|
self._pop_token(tokens) if len(tokens) else None for _ in range(
|
|
0, 4
|
|
)
|
|
]
|
|
|
|
def _pop_token(self, tokens):
|
|
token = tokens.pop(0)
|
|
return token if len(token) > 0 else None
|