Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[PR196 0/3] Cleanup of integrated test harness, other small fixes #247

Merged
merged 11 commits into from
Dec 21, 2015
Merged
98 changes: 62 additions & 36 deletions catkin_tools/commands/catkin.py
Original file line number Diff line number Diff line change
Expand Up @@ -81,15 +81,66 @@ def create_subparsers(parser, verbs):
return argument_preprocessors


def main(sysargs=None):
def expand_one_verb_alias(sysargs, verb_aliases, used_aliases):
"""Iterate through sysargs looking for expandable verb aliases.

When a verb alias is found, sysargs is modified to effectively expand the alias.
The alias is removed from verb_aliases and added to used_aliases.
After finding and expanding an alias, this function returns True.
If no alias is found to be expanded, this function returns False.
"""
cmd = os.path.basename(sys.argv[0])
for index, arg in enumerate(sysargs):
if arg.startswith('-'):
# Not a verb, continue through the arguments
continue
if arg in used_aliases:
print(fmt(
"@!@{gf}==>@| Expanding alias '@!@{yf}" + arg +
"@|' was previously expanded, ignoring this time to prevent infinite recursion."
))
if arg in verb_aliases:
before = [] if index == 0 else sysargs[:index - 1]
after = [] if index == len(sysargs) else sysargs[index + 1:]
sysargs[:] = before + verb_aliases[arg].split() + after
print(fmt(
"@!@{gf}==>@| Expanding alias "
"'@!@{yf}{alias}@|' "
"from '@{yf}{before} @!{alias}@{boldoff}{after}@|' "
"to '@{yf}{before} @!{expansion}@{boldoff}{after}@|'"
).format(
alias=arg,
expansion=verb_aliases[arg],
before=' '.join([cmd] + before),
after=(' '.join([''] + after) if after else '')
))
# Prevent the alias from being used again, to prevent infinite recursion
used_aliases.append(arg)
del verb_aliases[arg]
# Return True since one has been found
return True
# Return False since no verb alias was found
return False


def expand_verb_aliases(sysargs, verb_aliases):
"""Expands aliases in sysargs which are found in verb_aliases until none are found."""
used_aliases = []
while expand_one_verb_alias(sysargs, verb_aliases, used_aliases):
pass
return sysargs


def catkin_main(sysargs):
# Initialize config
try:
initialize_config()
except RuntimeError as exc:
sys.exit("Failed to initialize config: {0}".format(exc))

# Create a top level parser
parser = argparse.ArgumentParser(description="catkin command", formatter_class=argparse.RawDescriptionHelpFormatter)
parser = argparse.ArgumentParser(
description="catkin command", formatter_class=argparse.RawDescriptionHelpFormatter)
add = parser.add_argument
add('-a', '--list-aliases', action="store_true", default=False,
help="Lists the current verb aliases and then quits, all other arguments are ignored")
Expand All @@ -113,7 +164,6 @@ def main(sysargs=None):

# Setup sysargs
sysargs = sys.argv[1:] if sysargs is None else sysargs
cmd = os.path.basename(sys.argv[0])

# Get colors config
no_color = False
Expand Down Expand Up @@ -144,39 +194,8 @@ def main(sysargs=None):
if not arg.startswith('-'):
break

# Do alias expansion
expanding_verb_aliases = True
used_aliases = []
while expanding_verb_aliases:
expanding_verb_aliases = False
for index, arg in enumerate(sysargs):
if not arg.startswith('-'):
if arg in used_aliases:
print(fmt(
"@!@{gf}==>@| Expanding alias '@!@{yf}" +
arg +
"@|' was previously expanded, ignoring this time to prevent infinite recursion."
))
if arg in verb_aliases:
before = [] if index == 0 else sysargs[:index - 1]
after = [] if index == len(sysargs) else sysargs[index + 1:]
sysargs = before + verb_aliases[arg].split() + after
print(fmt(
"@!@{gf}==>@| Expanding alias "
"'@!@{yf}{alias}@|' "
"from '@{yf}{before} @!{alias}@{boldoff}{after}@|' "
"to '@{yf}{before} @!{expansion}@{boldoff}{after}@|'"
).format(
alias=arg,
expansion=verb_aliases[arg],
before=' '.join([cmd] + before),
after=(' '.join([''] + after) if after else '')
))
expanding_verb_aliases = True
# Prevent the alias from being used again, to prevent infinite recursion
used_aliases.append(arg)
del verb_aliases[arg]
break
# Do verb alias expansion
sysargs = expand_verb_aliases(sysargs, verb_aliases)

# Determine the verb, splitting arguments into pre and post verb
verb = None
Expand Down Expand Up @@ -217,3 +236,10 @@ def main(sysargs=None):
# Finally call the subparser's main function with the processed args
# and the extras which the preprocessor may have returned
sys.exit(args.main(args) or 0)


def main(sysargs=None):
try:
catkin_main(sysargs)
except KeyboardInterrupt:
print('Interrupted by user!')
57 changes: 40 additions & 17 deletions catkin_tools/context.py
Original file line number Diff line number Diff line change
Expand Up @@ -54,25 +54,28 @@ class Context(object):
DEFAULT_DEVEL_SPACE = 'devel'
DEFAULT_INSTALL_SPACE = 'install'

STORED_KEYS = ['extend_path',
'source_space',
'build_space',
'devel_space',
'install_space',
'isolate_devel',
'install',
'isolate_install',
'cmake_args',
'make_args',
'use_internal_make_jobserver',
'catkin_make_args',
'whitelist',
'blacklist']
STORED_KEYS = [
'extend_path',
'source_space',
'build_space',
'devel_space',
'install_space',
'isolate_devel',
'install',
'isolate_install',
'cmake_args',
'make_args',
'use_internal_make_jobserver',
'catkin_make_args',
'whitelist',
'blacklist',
]

KEYS = STORED_KEYS + [
'workspace',
'profile',
'space_suffix']
'space_suffix',
]

@classmethod
def load(
Expand Down Expand Up @@ -200,7 +203,8 @@ def __init__(
catkin_make_args=None,
space_suffix=None,
whitelist=None,
blacklist=None
blacklist=None,
**kwargs
):
"""Creates a new Context object, optionally initializing with parameters

Expand Down Expand Up @@ -242,6 +246,10 @@ def __init__(
"""
self.__locked = False

# Check for unhandled context options
if len(kwargs) > 0:
print('Warning: Unhandled config context options: {}'.format(kwargs))

# Validation is done on assignment
# Handle *space assignment and defaults
self.workspace = workspace
Expand Down Expand Up @@ -325,7 +333,7 @@ def load_env(self):

self.env_cmake_prefix_path = ':'.join(split_result_cmake_prefix_path[1:])
else:
self.env_cmake_prefix_path = os.environ.get('CMAKE_PREFIX_PATH', '')
self.env_cmake_prefix_path = os.environ.get('CMAKE_PREFIX_PATH', '').rstrip(':')

# Add warnings based on conflicing CMAKE_PREFIX_PATH
if self.cached_cmake_prefix_path and self.extend_path:
Expand Down Expand Up @@ -673,3 +681,18 @@ def blacklist(self):
@blacklist.setter
def blacklist(self, value):
self.__blacklist = value

def package_build_space(self, package):
return os.path.join(self.build_space_abs, package.name)

def package_devel_space(self, package):
if self.isolate_devel:
return os.path.join(self.devel_space_abs, package.name)
else:
return self.devel_space_abs

def package_install_space(self, package):
if self.isolate_install:
return os.path.join(self.install_space_abs, package.name)
else:
return self.install_space_abs
4 changes: 2 additions & 2 deletions catkin_tools/make_jobserver.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,10 +29,10 @@
from catkin_tools.common import log
from catkin_tools.common import version_tuple

JOBSERVER_SUPPORT_MAKEFILE = b'''
JOBSERVER_SUPPORT_MAKEFILE = b"""
all:
\techo $(MAKEFLAGS) | grep -- '--jobserver-fds'
'''
"""


def memory_usage():
Expand Down
13 changes: 13 additions & 0 deletions catkin_tools/resultspace.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,16 @@
# Copyright 2015 Open Source Robotics Foundation, Inc.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

import os
import re
Expand Down
2 changes: 1 addition & 1 deletion catkin_tools/runner/run_windows.py
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ def run_command(cmd, cwd=None):
left_over = lines[-1]
try:
yield data.decode()
except UnicodeDecodeError as exc:
except UnicodeDecodeError:
yield unicode(data, errors='ignore')
# Done
yield p.returncode
4 changes: 2 additions & 2 deletions catkin_tools/terminal_color.py
Original file line number Diff line number Diff line change
Expand Up @@ -124,15 +124,15 @@ def sanitize(msg):
return msg


def fmt(msg):
def fmt(msg, reset=True):
"""Replaces color annotations with ansi escape sequences"""
global _ansi
msg = msg.replace('@!', '@{boldon}')
msg = msg.replace('@/', '@{italicson}')
msg = msg.replace('@_', '@{ulon}')
msg = msg.replace('@|', '@{reset}')
t = ColorTemplate(msg)
return t.substitute(_ansi) + ansi('reset')
return t.substitute(_ansi) + (ansi('reset') if reset else '')


def test_colors():
Expand Down
6 changes: 0 additions & 6 deletions catkin_tools/verbs/catkin_build/common.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,12 +18,6 @@
import stat
import sys

from multiprocessing import cpu_count

from catkin_tools.runner import run_command

from .color import clr

# Due to portability issues, it uses only POSIX-compliant shell features.
# This means that there is no support for BASH-like arrays, and special
# care needs to be taken in order to preserve argument atomicity when
Expand Down
6 changes: 6 additions & 0 deletions catkin_tools/verbs/catkin_build/job.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,12 @@
from .common import generate_env_file
from .common import get_python_install_dir

# FileNotFoundError is only defined in Python3, but IOError can be used.
try:
FileNotFoundError
except NameError:
FileNotFoundError = IOError

MAKE_EXEC = which('make')
CMAKE_EXEC = which('cmake')

Expand Down
2 changes: 0 additions & 2 deletions catkin_tools/verbs/catkin_create/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,6 @@
# See the License for the specific language governing permissions and
# limitations under the License.

from catkin_tools.argument_parsing import argument_preprocessor

from .cli import main
from .cli import prepare_arguments

Expand Down
3 changes: 0 additions & 3 deletions catkin_tools/verbs/catkin_list/cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,15 +14,12 @@

from __future__ import print_function

import os
import sys

from catkin_tools.argument_parsing import add_context_args

from catkin_tools.context import Context

from catkin_tools.metadata import find_enclosing_workspace

from catkin_pkg.packages import find_packages
from catkin_pkg.package import InvalidPackage

Expand Down
15 changes: 11 additions & 4 deletions tests/README.md
Original file line number Diff line number Diff line change
@@ -1,10 +1,17 @@
Testing
=======

The `catkin_tools` test harness includes the following
types of tests, organized into different directories:
The `catkin_tools` test harness includes the following types of tests,
organized into different directories:

* **unit** -- API tests for the `catkin_tools` python interface
* **integrated** -- Full integration tests for different workflows
* **system** -- Tests which not only test integrated parts of catkin_tools but the interaction with other, external projects like catkin_pkg and catkin.
* **system** -- Tests which not only test integrated parts of `catkin_tools`
but the interaction with other, external projects like catkin_pkg and catkin.

## Running Tests

To run all tests and view the output, run the following in this directory:

```
nosetests -s
```
Loading