Skip to content
This repository has been archived by the owner on Jan 14, 2024. It is now read-only.

Commit

Permalink
#59: Added --import commandline switch by adding an argument preparsi…
Browse files Browse the repository at this point in the history
…ng mechanism
  • Loading branch information
blackandred committed Nov 23, 2020
1 parent 24619a5 commit 620b952
Show file tree
Hide file tree
Showing 4 changed files with 72 additions and 10 deletions.
14 changes: 9 additions & 5 deletions src/rkd/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -39,22 +39,25 @@ def prepend_development_paths():
sys.path = [os.getcwd() + '/src'] + sys.path

def main(self, argv: list):
if not argv[1:]:
if not CommandlineParsingHelper.has_any_task(argv) and not CommandlineParsingHelper.was_help_used(argv):
self.print_banner_and_exit()

# system wide IO instance with defaults, the :init task should override those settings
io = SystemIO()
io.silent = True
io.set_log_level(os.getenv('RKD_SYS_LOG_LEVEL', 'info'))

# preparse arguments that are before tasks
preparsed_args = CommandlineParsingHelper.preparse_args(argv)

# load context of components - all tasks, plugins etc.
try:
self._ctx = ContextFactory(io).create_unified_context(
additional_imports=os.getenv('RKD_IMPORTS', '').split(':') if os.getenv('RKD_IMPORTS') else []
)
self._ctx = ContextFactory(io).create_unified_context(additional_imports=preparsed_args['imports'])

except ParsingException as e:
io.silent = False
io.error_msg('Cannot import tasks/module from RKD_IMPORTS environment variable. Details: {}'.format(str(e)))
io.error_msg('Cannot import tasks/module from RKD_IMPORTS environment variable or --import switch. '
'Details: {}'.format(str(e)))
sys.exit(1)

except YamlParsingException as e:
Expand Down Expand Up @@ -94,6 +97,7 @@ def main():

try:
app.main(argv=sys.argv)

except TaskNotFoundException as e:
print(e)
sys.exit(127)
Expand Down
57 changes: 55 additions & 2 deletions src/rkd/argparsing.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
#!/usr/bin/env python3

import os
from typing import List
from typing import Tuple
from argparse import ArgumentParser
Expand Down Expand Up @@ -157,12 +158,12 @@ def parse(cls, task: TaskDeclarationInterface, args: list) -> Tuple[dict, dict]:
argparse.add_argument('--become', '-rb', help='Execute task as given user (requires sudo)', default='')

task.get_task_to_execute().configure_argparse(argparse)
cls.add_env_variables_to_argparse(argparse, task)
cls.add_env_variables_to_argparse_description(argparse, task)

return vars(argparse.parse_args(args)), argparse.traced_arguments

@classmethod
def add_env_variables_to_argparse(cls, argparse: ArgumentParser, task: TaskDeclarationInterface):
def add_env_variables_to_argparse_description(cls, argparse: ArgumentParser, task: TaskDeclarationInterface):
if argparse.description is None:
argparse.description = ""

Expand All @@ -180,3 +181,55 @@ def add_env_variables_to_argparse(cls, argparse: ArgumentParser, task: TaskDecla

if not task.get_task_to_execute().get_declared_envs():
argparse.description += ' -- No environment variables declared -- '

@staticmethod
def preparse_args(args: List[str]):
"""
Parses commandline arguments which are not accessible on tasks level, but are accessible behind tasks
Those arguments should decide about RKD core behavior on very early stage
:param args:
:return:
"""

limited_args = []

for arg in args:
if arg.startswith(':') or arg.startswith('@'):
break

limited_args.append(arg)

argparse = ArgumentParser(add_help=False)
argparse.add_argument('--import', '-ri')

parsed = vars(argparse.parse_known_args(args=limited_args)[0])

return {
'imports': list(filter(None,
os.getenv('RKD_IMPORT', parsed['import'] if parsed['import'] else '').split(':')
))
}

@staticmethod
def has_any_task(argv: List[str]) -> bool:
"""
Checks if arguments contains at least one task
:param argv:
:return:
"""

for arg in argv:
if arg.startswith(':'):
return True

return False

@staticmethod
def was_help_used(argv: List[str]) -> bool:
for arg in argv:
if arg in ['-h', '--help']:
return True

return False
7 changes: 6 additions & 1 deletion src/rkd/standardlib/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -40,14 +40,19 @@ def get_declared_envs(self) -> Dict[str, str]:
'RKD_ALIAS_GROUPS': '', # supported by core, here only for documentation in CLI
'RKD_UI': 'true',
'RKD_SYS_LOG_LEVEL': 'info', # supported by core, here only for documentation in CLI
'RKD_IMPORTS': '' # supported by core, here only for documentation in CLI
'RKD_IMPORT': '' # supported by core, here only for documentation in CLI
}

def configure_argparse(self, parser: ArgumentParser):
parser.add_argument('--no-ui', '-n', action='store_true',
help='Do not display RKD interface (similar to --silent, ' +
'but does not inherit --silent into next tasks)')

parser.add_argument('--import', '-ri',
help='Imports a task or list of tasks separated by ":". '
'Example: "rkt_utils.docker:rkt_ciutils.boatci:rkd_python". '
'Instead of switch there could be also environment variable "RKD_IMPORT" used')

def execute(self, context: ExecutionContext) -> bool:
"""
:init task is setting user-defined global defaults on runtime
Expand Down
4 changes: 2 additions & 2 deletions test/test_argparsing.py
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ def test_add_env_variables_to_argparse(self):
parser = ArgumentParser(':test')
task = get_test_declaration()

CommandlineParsingHelper.add_env_variables_to_argparse(parser, task)
CommandlineParsingHelper.add_env_variables_to_argparse_description(parser, task)
self.assertIn('ORG_NAME (default: International Workers Association)', parser.description)

def test_add_env_variables_to_argparse__no_envs(self):
Expand All @@ -44,7 +44,7 @@ def test_add_env_variables_to_argparse__no_envs(self):
# empty the values
task.get_task_to_execute().get_declared_envs = lambda: {}

CommandlineParsingHelper.add_env_variables_to_argparse(parser, task)
CommandlineParsingHelper.add_env_variables_to_argparse_description(parser, task)
self.assertNotIn('ORG_NAME (default: International Workers Association)', parser.description)
self.assertIn('-- No environment variables declared --', parser.description)

Expand Down

0 comments on commit 620b952

Please sign in to comment.