#!/home/docs/checkouts/readthedocs.org/user_builds/pyctest/conda/latest/bin/python
# MIT License
#
# Copyright (c) 2018, The Regents of the University of California,
# through Lawrence Berkeley National Laboratory (subject to receipt of any
# required approvals from the U.S. Dept. of Energy). All rights reserved.
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to deal
# in the Software without restriction, including without limitation the rights
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
# copies of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in all
# copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
# SOFTWARE.
#
from __future__ import absolute_import
__author__ = "Jonathan Madsen"
__copyright__ = "Copyright 2018, The Regents of the University of California"
__credits__ = ["Jonathan Madsen"]
__license__ = "MIT"
__version__ = "0.0.12"
__maintainer__ = "Jonathan Madsen"
__email__ = "jonrobm.programming@gmail.com"
__status__ = "Development"
__all__ = ['Conda', 'FindExePath', 'RemovePath', 'Cleanup', 'GetHomePath',
'GetSystemVersionInfo', 'ArgumentParser']
import os
import re
import sys
import shutil
import socket
import platform
import warnings
import argparse
import textwrap as _textwrap
from . import pyctest
from . import pycmake
#------------------------------------------------------------------------------#
#
[docs]class Conda(object):
"""Utility class for getting relevant conda environment variables"""
def __init__(self):
self.prefix = os.environ.get("CONDA_PREFIX")
self.environ = os.environ.get("CONDA_ENVIRONMENT")
self.python = os.environ.get("CONDA_PYTHON_EXE")
self.default_env = os.environ.get("CONDA_DEFAULT_ENV")
self.shlvl = os.environ.get("CONDA_SHLVL")
def __str__(self):
return "{}={};{}={};{}={};{}={};{}={}".format(
"CONDA_PREFIX", self.prefix,
"CONDA_ENVIRONMENT", self.environ,
"CONDA_PYTHON_EXE", self.python,
"CONDA_DEFAULT_ENV", self.default_env,
"CONDA_SHLVL", self.shlvl)
#------------------------------------------------------------------------------#
#
[docs]def FindExePath(name, path=None):
"""Function for finding the path to an executable"""
try:
from shutil import which
exepath = which(name, path=path)
if exepath is not None:
return exepath
except:
pass
try:
from distutils.spawn import find_executable
return find_executable(name, path=path)
except:
pass
return None
#------------------------------------------------------------------------------#
#
[docs]def RemovePath(path):
"""Function for safely removing a folder"""
try:
import shutil
if path is not None and os.path.exists(path):
if os.path.isdir(path) and path != os.getcwd():
shutil.rmtree(path)
else:
os.remove(path)
except Exception as e:
print("non-fatal exception on '{}': {}".format(path, e))
#------------------------------------------------------------------------------#
#
[docs]def Cleanup(path=None, extra=[], exclude=[]):
"""
This function removes PyCTest files/folders that are copied into or
generated in the given path during running PyCTest
Parameters
----------
path : str, optional
alternative path (default=pyctest.SOURCE_DIRECTORY)
extra : list, optional
any additional files/folders to remove
exclude : list, optional
use this to exclude deleting files/folders
"""
filelist = ["CTestConfig.cmake", "CTestCustom.cmake",
"CTestTestfile.cmake",
"DartConfiguration.tcl",
"Init.cmake", "Stages.cmake", "Utilities.cmake",
"Makefile", "Testing",
"cmake_install.cmake", "__pycache__",
"CMakeFiles", "CMakeCache.txt"]
if len(extra) > 0:
filelist.extend(extra)
for f in exclude:
if f in filelist:
filelist.remove(f)
if path is None:
path = pyctest.SOURCE_DIRECTORY
for f in filelist:
RemovePath(os.path.join(path, f))
#------------------------------------------------------------------------------#
#
[docs]def GetHomePath():
"""Get the user's home drive for the operating system"""
home = os.environ.get("HOME")
if home is None:
home_d = os.environ.get("HomeDrive")
home_p = os.environ.get("HomePath")
if home_d is not None and home_p is not None:
home = os.path.join(home_d, home_p)
return home
#------------------------------------------------------------------------------#
#
[docs]def GetSystemVersionInfo():
"""Version info for operating system"""
version_info = "{}".format(platform.system())
if platform.system() == "Windows":
version_info = "Windows {}".format(platform.version())
if platform.system() == 'Darwin':
version_info = "macOS {}".format(platform.mac_ver()[0])
elif platform.system() == 'Linux':
version_info = "{} {}".format(platform.linux_distribution()[0],
platform.linux_distribution()[1])
return version_info
#-------------------------------------------------------------------------#
#
def _get_verbosity():
'''Determine the verbosity
Default: 1
'''
verbose = os.environ.get("PYCTEST_VERBOSE")
if verbose is not None:
verbose = int(verbose)
else:
verbose = 1
return verbose
#-------------------------------------------------------------------------#
#
def _get_verbosity_flag():
'''Determine the initial verbosity flag based verbose setting
Default: "-V"
'''
verbose = _get_verbosity()
if verbose < 1:
return ""
elif verbose == 1:
return "-V"
elif verbose == 2:
return "-VV"
elif verbose > 2:
return "--debug"
#------------------------------------------------------------------------------#
#
class LineWrapRawTextHelpFormatter(argparse.RawDescriptionHelpFormatter):
def __init__(self, prog, indent_increment=2, max_help_position=80, width=160):
super(argparse.RawDescriptionHelpFormatter, self).__init__(
prog=prog, indent_increment=indent_increment,
max_help_position=max_help_position, width=width)
def _split_lines(self, text, width):
#print("Splitting lines...\n\tTEXT: {}\n\tWIDTH:{}\n".format(text, width))
#text = self._whitespace_matcher.sub(' ', text).strip()
return _textwrap.wrap(text, width)
#------------------------------------------------------------------------------#
#
[docs]class ArgumentParser(argparse.ArgumentParser):
"""Adds common command-line options for PyCTest
Note:
Inherit from this class to create custom options
Parameters
----------
project_name: str
Name of the project
source_dir: str
relative path to the source code
binary_dir: str
relative path to the binary (build) directory
mode: str='Continuous', optional
Workflow setting
Options: Start, Update, Configure, Build, Test, Coverage, MemCheck, Submit, Stages
stages: list=['Start', 'Update', 'Configure', 'Build', 'Test', 'Coverage', 'MemCheck']
In "Stages" mode, these are the workflow components to execute
If a command for the stage is not set, e.g. CTEST_COVERAGE_COMMAND is not
set, then the stage is skipped
trigger: str='None', optional
Deprecated, has no effect
model: str='Continuous', optional
Submission track. Common choices: Continuous, Nightly, Experimental
site: str = platform.node(), optional
The ID of the submission site
jobs: int = 1, optional
Number of tests to execute in parallel
submit: bool, optional
Enable/disable submission by default
vcs_type: str, optional
Version control type: bzr, cvs, git, hg, p4, svn
checkout_command: str, optional
Define the default checkout command
update_command: str, optional
Define the default update command
configure_command: str, optional
Define the default configure command
build_command: str, optional
Define the default configure command
coverage_command: str, optional
Define the default coverage command
memcheck_command: str, optional
Define the default memory check command
build_choices: str, optional
If running CMake, define the build type [Release, RelWithDebInfo, Debug, MinSizeRel]
use_launchers: bool, optional
For build trees generated by CMake using one of the Makefile Generators or the Ninja generator,
specify whether the CTEST_USE_LAUNCHERS feature is enabled by the CTestUseLaunchers module
(also included by the CTest module). When enabled, the generated build system wraps each
invocation of the compiler, linker, or custom command line with a "launcher" that communicates
with CTest via environment variables and files to report granular build warning and error
information. Otherwise, CTest must "scrape" the build output log for diagnostics.
cleanup_extra: list, optional
When `--pyctest-cleanup` or `--pyctest-clean-first` is invoked, these additional
files/folders will be removed
cleanup_exclude: list, optional
When `--pyctest-cleanup` or `--pyctest-clean-first` is invoked, these additional
files/folders will be excluded from removal
cdash_version: str=None, optional
Specify the version of CDash on the server
submit_retry_count: int=1, optional
Specify a number of attempts to retry submission on network failure
submit_retry_delay: int=30, optional
Specify a delay before retrying submission on network failure
curl_options: list=None, optional
Curl options: 'CURLOPT_SSL_VERIFYPEER_OFF' and 'CURLOPT_SSL_VERIFYHOST_OFF'
drop_location: str="/submit.php?project={}".format(project_name), optional
The path on the dashboard server to send the submission
drop_method: str="https", optional
Specify the method by which results should be submitted to the dashboard server.
The value may be cp, ftp, http, https, scp, or xmlrpc (if CMake was built with support for it)
drop_site: str="cdash.nersc.gov", optional
The dashboard server name (for ftp, http, and https, scp, and xmlrpc)
drop_site_password: str=None, optional
The dashboard server login password, if any (for ftp, http, and https).
drop_site_user: str=None, optional
The dashboard server login user name, if any (for ftp, http, and https).
nightly_start_time: str="01:00:00 UTC", optional
In the Nightly dashboard mode, specify the "nightly start time". With
centralized version control systems (cvs and svn), the Update step checks
out the version of the software as of this time so that multiple clients
choose a common version to test. This is not well-defined in distributed
version-control systems so the setting is ignored.
"""
#-------------------------------------------------------------------------#
#
def __init__(self,
project_name,
source_dir,
binary_dir,
vcs_type=None,
cleanup_extra=[],
cleanup_exclude=[],
drop_method="https",
drop_site="cdash.nersc.gov",
drop_location="/submit.php?project=${CTEST_PROJECT_NAME}",
drop_site_user=None,
drop_site_password=None,
use_launchers=False,
submit_retry_count=1,
submit_retry_delay=30,
curl_options=None,
cdash_version=None,
nightly_start_time="01:00:00 UTC",
jobs=1,
submit=False,
stages=["Start", "Update", "Configure", "Build", "Test", "Coverage", "MemCheck"],
trigger="None",
site=socket.gethostname().strip('.local'),
ctest_args=[_get_verbosity_flag()],
mode="Stages",
checkout_command=None,
update_command=None,
configure_command=None,
build_command=None,
coverage_command=None,
memcheck_command=None,
python_exe=sys.executable,
build_type=None,
model="Continuous",
build_choices=["Release", "RelWithDebInfo", "Debug", "MinSizeRel"],
# standard argparse.ArgumentParser arguments
prog=None,
usage=None,
description="PyCTest argparse. Arguments after first '--' are passed directly " \
"to CTest, arguments after second '--' are passed directly to CMake",
epilog=None,
parents=[],
formatter_class=LineWrapRawTextHelpFormatter,
prefix_chars='-',
fromfile_prefix_chars=None,
argument_default=None,
conflict_handler='resolve',
add_help=True):
# initilize parent
super(ArgumentParser, self).__init__(prog=prog,
usage=usage,
description=description,
epilog=epilog, parents=parents,
formatter_class=formatter_class,
prefix_chars=prefix_chars,
fromfile_prefix_chars=fromfile_prefix_chars,
argument_default=argument_default,
conflict_handler=conflict_handler,
add_help=add_help)
self.checkout_command = checkout_command
self.update_command = checkout_command
self.configure_command = configure_command
self.build_command = build_command
self.coverage_command = coverage_command
self.memcheck_command = memcheck_command
self.cleanup_extra = cleanup_extra
self.cleanup_exclude = cleanup_exclude
if checkout_command is not None:
pyctest.CHECKOUT_COMMAND = "{}".format(checkout_command)
if update_command is not None:
pyctest.UPDATE_COMMAND = "{}".format(update_command)
if configure_command is not None:
pyctest.CONFIGURE_COMMAND = "{}".format(configure_command)
if build_command is not None:
pyctest.BUILD_COMMAND = "{}".format(build_command)
if coverage_command is not None:
pyctest.COVERAGE_COMMAND = "{}".format(coverage_command)
if memcheck_command is not None:
pyctest.MEMORYCHECK_COMMAND = "{}".format(memcheck_command)
# limit the mode choices
mode_choices = ["Start", "Update", "Configure", "Build",
"Test", "Coverage", "MemCheck", "Submit", "Stages"]
# stage choices
stage_choices = ["Start", "Update", "Configure", "Build",
"Test", "Coverage", "MemCheck", "Submit"]
# choices for submission model
model_choices = ["Nightly", "Continuous", "Experimental"]
# choices for submit trigger
trigger_choices = ["Build", "Test", "Coverage", "MemCheck", "None"]
# version control options
vcs_choices = ["bzr", "cvs", "git", "hg", "p4", "svn"]
#---------------------------------------------------------------------#
self.add_argument("-F", # clean [F]irst
"--pyctest-clean-first",
help="Remove standard PyCTest files and binary directory (if not source directory)",
action="store_true")
self.add_argument("-S", # [S]ubmit
"--pyctest-submit",
help="Enable submission to dashboard",
action='store_true',
default=submit)
self.add_argument("-A", # [A]ppend
"--pyctest-append",
help="Append to last invocation of CTest",
action='store_true')
#---------------------------------------------------------------------#
self.add_argument("-j", # [J]obs
"--pyctest-jobs",
help="number of concurrent jobs",
type=int,
metavar='<INT>',
default=jobs)
self.add_argument("-m", # [M]ode
"--pyctest-mode",
help="Run specific stage. Choices: [{}]".format(",".join(mode_choices)),
type=str,
choices=mode_choices,
metavar='<TYPE>',
default=mode)
self.add_argument("-b", # [B]uild name
"--pyctest-build-name",
type=str,
default=None,
metavar='<NAME>',
help="Build name for identification")
self.add_argument("-i", # source -> [I]nput
"--pyctest-source-dir",
help="Source directory",
type=str,
metavar="<PATH>",
default=source_dir)
self.add_argument("-o", # binary -> [O]utput
"--pyctest-binary-dir",
help="Binary/build/working directory",
type=str,
metavar="<PATH>",
default=binary_dir)
#---------------------------------------------------------------------#
self.add_argument("-M", # [M]odel
"--pyctest-model",
help="CTest submission model (track). Choices: [{}]".format(",".join(model_choices)),
type=str,
metavar='<TYPE>',
choices=model_choices,
default=model)
self.add_argument("-H", # [H]ost
"--pyctest-site",
help="CTest submission site",
type=str,
metavar='<SITE>',
default=site)
self.add_argument("-P", # [P]ython exe
"--pyctest-python-exe",
help="Python executable to use. This can be absolue, relative, or CMake path",
type=str,
metavar='<EXE>',
default=python_exe)
self.add_argument("-N", # [N]ame
"--pyctest-project-name",
help="Name of project using PyCTest",
type=str,
metavar='<NAME>',
default=project_name)
#---------------------------------------------------------------------#
self.add_argument("-C", # [C]lean
"--pyctest-cleanup",
help="Remove standard PyCTest files and binary directory (if not source directory) and exit",
nargs='+',
metavar='<PATH>',
type=str)
self.add_argument("-L", # [L]abels
"--pyctest-subproject-labels",
help="Add labels for subproject",
metavar='<LABEL>',
nargs='+',
type=str)
self.add_argument("-T", # [T]est-action
"--pyctest-stages",
help="Run multiple stages. Choices: [{}]".format(",".join(stage_choices)),
type=str,
choices=stage_choices,
default=stages,
metavar="<TYPE>",
nargs='*')
#---------------------------------------------------------------------#
self.add_argument("-fc", # [F]ortran compiler
"--pyctest-fortran-compiler",
help="Specify Fortan compiler (if needed)",
default=os.environ.get("FC"),
metavar='<EXE>',
type=str)
self.add_argument("-cc", # [CC] compiler
"--pyctest-c-compiler",
help="Specify the C compiler (if needed)",
default=os.environ.get("CC"),
metavar='<EXE>',
type=str)
self.add_argument("-cxx", # [CXX] compiler
"--pyctest-cxx-compiler",
help="Specify C++ compiler (if needed)",
default=os.environ.get("CXX"),
metavar='<EXE>',
type=str)
#---------------------------------------------------------------------#
self.add_argument("--pyctest-token",
help="CTest site token for submission",
metavar='<TOKEN>',
type=str)
self.add_argument("--pyctest-token-file",
help="Path to file for CTest site token for submission",
metavar='<FILE>',
type=str)
self.add_argument("--pyctest-vcs-type",
help="""Set to enable revision ID discovery during the Update stage. Choices: [{}]""".format(",".join(vcs_choices)),
default=vcs_type,
type=str,
metavar="<TYPE>",
choices=vcs_choices)
self.add_argument("--pyctest-build-type",
help="""Specify CMAKE_BUILD_TYPE (if using CMake). Choices: [{}]""".format(",".join(build_choices)),
default=build_type,
type=str,
metavar='<TYPE>',
choices=build_choices)
self.add_argument("--pyctest-trigger",
help="DEPRECATED",
metavar='<TYPE>',
type=str,
choices=trigger_choices,
default=trigger)
self.add_argument("--pyctest-use-launchers",
default=use_launchers,
metavar='<BOOL>',
help="Enable launchers")
self.add_argument("--pyctest-ctest-args",
help="CTest arguments",
type=str,
default=ctest_args,
metavar='<ARG>',
nargs='*')
#---------------------------------------------------------------------#
def _add_argument(option_name, option_type, option_default):
ctest_var = "CTEST_" + option_name.upper()
web = "https://cmake.org/cmake/help/latest/variable/"
web = "{0}/{1}.html#variable:{1}".format(web, ctest_var)
option_name = option_name.lower().replace('_', '-')
self.add_argument("--pyctest-{}".format(option_name.lower()),
help="Set CTest variable: '{}'".format(ctest_var),
type=option_type,
metavar="<{}>".format(option_type.__name__.upper()),
#metavar="<{}>".format(option_name.upper().replace('-', '_')),
default=option_default)
_add_argument("cdash_version", str, cdash_version)
_add_argument("submit_retry_count", int, submit_retry_count)
_add_argument("submit_retry_delay", int, submit_retry_delay)
_add_argument("curl_options", list, curl_options)
_add_argument("drop_location", str, drop_location)
_add_argument("drop_method", str, drop_method)
_add_argument("drop_site", str, drop_site)
_add_argument("drop_site_password", str, drop_site_password)
_add_argument("drop_site_user", str, drop_site_user)
_add_argument("nightly_start_time", str, nightly_start_time)
self.add_argument("--pyctest-update-version-only",
help="""Specify that you want the version control update command to only discover the current version that is checked out, and not to update to a different version""",
action='store_true')
#-------------------------------------------------------------------------#
#
[docs] def process_args(self, args):
"""Process PyCTest args"""
binary_dir = os.path.realpath(args.pyctest_binary_dir)
source_dir = os.path.realpath(args.pyctest_source_dir)
# cleanup
if args.pyctest_cleanup:
for dir in args.pyctest_cleanup:
Cleanup(dir, self.cleanup_extra, self.cleanup_exclude)
if source_dir != binary_dir:
RemovePath(binary_dir)
sys.exit(0)
if args.pyctest_c_compiler is not None:
os.environ["CC"] = "{}".format(args.pyctest_c_compiler)
if args.pyctest_cxx_compiler is not None:
os.environ["CXX"] = "{}".format(args.pyctest_cxx_compiler)
if args.pyctest_fortran_compiler is not None:
os.environ["FC"] = "{}".format(args.pyctest_fortran_compiler)
# clean
if args.pyctest_clean_first:
Cleanup(binary_dir, self.cleanup_extra, self.cleanup_exclude)
if source_dir != binary_dir:
RemovePath(binary_dir)
# make binary directory
if not os.path.exists(binary_dir):
os.makedirs(binary_dir)
if args.pyctest_mode != "Stages":
args.pyctest_stages = [args.pyctest_mode]
# if submit enabled but was not included in stages
if args.pyctest_submit and not "Submit" in args.pyctest_stages:
args.pyctest_stages.append("Submit")
# the name of the project
pyctest.PROJECT_NAME = args.pyctest_project_name
# source directory
pyctest.SOURCE_DIRECTORY = source_dir
# binary directory
pyctest.BINARY_DIRECTORY = binary_dir
# site of CDash submission
pyctest.SITE = args.pyctest_site
if (args.pyctest_site == platform.node() and
os.environ.get("CTEST_SITE") is not None):
pyctest.SITE = os.environ.get("CTEST_SITE")
# build type
if args.pyctest_build_type is not None:
pyctest.set("BUILD_TYPE", "{}".format(args.pyctest_build_type))
pyctest.set("CTEST_CONFIGURATION_TYPE", "{}".format(args.pyctest_build_type))
# build name for CDash
if args.pyctest_build_name is None:
pyctest.BUILD_NAME = "[{} {} {}] [Python {}]".format(
platform.uname()[0],
GetSystemVersionInfo(),
platform.uname()[4],
platform.python_version())
else:
pyctest.BUILD_NAME = "{}".format(args.pyctest_build_name)
# the Python to use with scripts
pyctest.PYTHON_EXECUTABLE = args.pyctest_python_exe
# submit after "Test" has been called
pyctest.TRIGGER = args.pyctest_trigger
# how to checkout the code
pyctest.CHECKOUT_COMMAND = ""
# the submission model in CDash (default = Nightly)
pyctest.MODEL = args.pyctest_model
# update
if args.pyctest_vcs_type is not None:
pyctest.set("CTEST_UPDATE_TYPE", "{}".format(args.pyctest_vcs_type))
# if specified to not remove an revision
if not args.pyctest_update_version_only:
pyctest.set("CTEST_UPDATE_VERSION_ONLY", "ON")
# custom variables
pyctest.CUSTOM_COVERAGE_EXCLUDE = "NONE"
pyctest.CUSTOM_MAXIMUM_NUMBER_OF_ERRORS = "200"
pyctest.CUSTOM_MAXIMUM_NUMBER_OF_WARNINGS = "300"
pyctest.CUSTOM_MAXIMUM_PASSED_TEST_OUTPUT_SIZE = "104857600"
if args.pyctest_token:
pyctest.set("CTEST_TOKEN", args.pyctest_token)
elif args.pyctest_token_file:
pyctest.set("CTEST_TOKEN_FILE", args.pyctest_token_file)
else:
home = GetHomePath()
if home is not None:
relpath = os.path.join(".tokens", pyctest.PROJECT_NAME)
token_path = os.path.join(home, relpath)
if os.path.exists(token_path):
print("Setting CTEST_TOKEN_FILE to '{}'...".format(token_path))
pyctest.set("CTEST_TOKEN_FILE", token_path)
if os.environ.get("CTEST_TOKEN") is not None:
pyctest.set("CTEST_TOKEN", os.environ.get("CTEST_TOKEN"))
# append the stages to the CTest args
args.pyctest_ctest_args.append(
"-DSTAGES={}".format(";".join(args.pyctest_stages)))
# instruct to execute Stages.cmake
args.pyctest_ctest_args.extend(["-S", "Stages.cmake"])
# add the number of jobs
if args.pyctest_jobs > 0:
args.pyctest_ctest_args.append("-j{}".format(args.pyctest_jobs))
# enable launchers
if args.pyctest_use_launchers:
pyctest.set("CTEST_USE_LAUNCHERS", "ON")
# add subproject labels
if args.pyctest_subproject_labels:
pyctest.set("CTEST_LABELS_FOR_SUBPROJECTS", ";".join(args.pyctest_subproject_labels))
# if the arguments were provided
if len(args.pyctest_ctest_args) > 0:
for _arg in args.pyctest_ctest_args:
pyctest.ARGUMENTS.extend(_arg.split(" "))
# if append
if args.pyctest_append:
pyctest.set("CTEST_APPEND", "ON")
def _process_argument(var, val):
if val is not None:
if isinstance(val, list):
val = ";".join(val)
pyctest.set("CTEST_{}".format(var.upper()),
"{}".format(val))
_process_argument("cdash_version", args.pyctest_cdash_version)
_process_argument("submit_retry_count", args.pyctest_submit_retry_count)
_process_argument("submit_retry_delay", args.pyctest_submit_retry_delay)
_process_argument("curl_options", args.pyctest_curl_options)
_process_argument("drop_location", args.pyctest_drop_location)
_process_argument("drop_method", args.pyctest_drop_method)
_process_argument("drop_site", args.pyctest_drop_site)
_process_argument("drop_site_password", args.pyctest_drop_site_password)
_process_argument("drop_site_user", args.pyctest_drop_site_user)
_process_argument("nightly_start_time", args.pyctest_nightly_start_time)
print("CTest arguments (default): '{}'".format(" ".join(pyctest.ARGUMENTS)))
#-------------------------------------------------------------------------#
[docs] def parse_args(self, *args, **kwargs):
"""Parse the arguments
Note:
Arguments following first double-dash ("--") are passed directly to `ctest`
Note:
Arguments following second double-dash ("--") are passed directly to `cmake`
"""
_argv = []
_ctest = []
_cmake = []
_argsets = [_argv, _ctest, _cmake]
_i = 0
_separator = '--'
for _arg in sys.argv[1:]:
if _arg == _separator:
_i += 1
if _i >= len(_argsets):
sys.exit(
"ERROR: Too many \"{}\" separators provided "
"(expected at most {}).".format(_separator,
len(_argsets) - 1))
else:
_argsets[_i].append(_arg)
try:
sys.argv[1:] = _argv
pyctest.ARGUMENTS.extend(_ctest)
pycmake.ARGUMENTS.extend(_cmake)
print("PyCTest args: {}".format(_argv))
print(" CTest args: {}".format(pyctest.ARGUMENTS + _ctest))
print(" CMake args: {}".format(pycmake.ARGUMENTS + _cmake))
except Exception as e:
msg = "\nCommand line argument error:\n\t{}\n".format(e)
warnings.warn(msg)
# read arguments (fail if unknown option)
pargs = super(ArgumentParser, self).parse_args(*args, **kwargs)
# process PyCTest args
self.process_args(pargs)
# return all args
return pargs