def tox_configure(config): # type: (Config) -> None verbosity2("original envconfigs: {}".format(list( config.envconfigs.keys()))) verbosity2("original envlist: {}".format(config.envlist)) verbosity2("original envlist_default: {}".format(config.envlist_default)) version = get_python_version() verbosity2("Python version: {}".format(version)) gh_actions_config = parse_config(config._cfg.sections) verbosity2("tox-gh-actions config: {}".format(gh_actions_config)) factors = get_factors(gh_actions_config, version) envlist = get_envlist_from_factors(config.envlist, factors) verbosity2("new envlist: {}".format(envlist)) if not is_running_on_actions(): verbosity1("tox is not running in GitHub Actions") verbosity1("tox-gh-actions won't override envlist") return elif is_env_specified(config): verbosity1("envlist is explicitly given via TOXENV or -e option") verbosity1("tox-gh-actions won't override envlist") return config.envlist_default = config.envlist = envlist
def _evaluated_env_list(self): tox_env_filter = os.environ.get("TOX_SKIP_ENV") tox_env_filter_re = re.compile( tox_env_filter) if tox_env_filter is not None else None visited = set() for name in self.config.envlist: if name in visited: continue visited.add(name) if tox_env_filter_re is not None and tox_env_filter_re.match(name): msg = "skip environment {}, matches filter {!r}".format( name, tox_env_filter_re.pattern) reporter.verbosity1(msg) continue yield name
def get_python_info(cmd): proc = subprocess.Popen( cmd + [VERSION_QUERY_SCRIPT], stdout=subprocess.PIPE, stderr=subprocess.PIPE, universal_newlines=True, ) out, err = proc.communicate() if not proc.returncode: try: result = json.loads(out) except ValueError as exception: failure = exception else: return result else: failure = "exit code {}".format(proc.returncode) reporter.verbosity1("{!r} cmd {!r} out {!r} err {!r} ".format( failure, cmd, out, err))
def create_session_view(package, temp_dir): """once we build a package we cannot return that directly, as a subsequent call might delete that package (in order to do its own build); therefore we need to return a view of the file that it's not prone to deletion and can be removed when the session ends """ if not package: return package package_dir = temp_dir.join("package") package_dir.ensure(dir=True) # we'll number the active instances, and use the max value as session folder for a new build # note we cannot change package names as PEP-491 (wheel binary format) # is strict about file name structure exists = [i.basename for i in package_dir.listdir()] file_id = max(chain((0,), (int(i) for i in exists if six.text_type(i).isnumeric()))) session_dir = package_dir.join(str(file_id + 1)) session_dir.ensure(dir=True) session_package = session_dir.join(package.basename) # if we can do hard links do that, otherwise just copy links = False if hasattr(os, "link"): try: os.link(str(package), str(session_package)) links = True except (OSError, NotImplementedError): pass if not links: package.copy(session_package) operation = "links" if links else "copied" common = session_package.common(package) verbosity1( "package {} {} to {} ({})".format( common.bestrelpath(session_package), operation, common.bestrelpath(package), common, ), ) return session_package
def start_container(image, mount_local=None, mount_to=None): try: container = CLIENT.containers.create( image, command=["sleep", "infinity"], auto_remove=False, detach=True, network_mode="host", volumes={mount_local: {"bind": str(mount_to), "mode": "Z"}} if mount_to and mount_local else None, ) except Exception as exception: reporter.error(repr(exception)) raise reporter.verbosity1( f"start container via {container.short_id} ({container.attrs['Name']}) based on {image}" ) container.start() return container
def tox_configure(config): # type: (Config) -> None verbosity1("running tox-gh-actions") if not is_running_on_actions(): verbosity1( "tox-gh-actions won't override envlist " "because tox is not running in GitHub Actions" ) return elif is_env_specified(config): verbosity1( "tox-gh-actions won't override envlist because " "envlist is explicitly given via TOXENV or -e option" ) return verbosity2("original envconfigs: {}".format(list(config.envconfigs.keys()))) verbosity2("original envlist_default: {}".format(config.envlist_default)) verbosity2("original envlist: {}".format(config.envlist)) versions = get_python_version_keys() verbosity2("Python versions: {}".format(versions)) gh_actions_config = parse_config(config._cfg.sections) verbosity2("tox-gh-actions config: {}".format(gh_actions_config)) factors = get_factors(gh_actions_config, versions) verbosity2("using the following factors to decide envlist: {}".format(factors)) envlist = get_envlist_from_factors(config.envlist, factors) config.envlist_default = config.envlist = envlist verbosity1("overriding envlist with: {}".format(envlist)) if is_running_on_container(): verbosity2( "not enabling problem matcher as tox seems to be running on a container" ) # Trying to add a problem matcher from a container without proper host mount can # cause an error like the following: # Unable to process command '::add-matcher::/.../matcher.json' successfully. else: verbosity2("enabling problem matcher") print("::add-matcher::" + get_problem_matcher_file_path()) if not is_log_grouping_enabled(config): verbosity2( "disabling log line grouping on GitHub Actions based on the configuration" )
def build_image(venv, context, action): create_docker_file(context, venv) # host -> Linux access local pip generator = CLIENT.api.build(path=str(context), rm=True, network_mode="host") image_id = None while True: output = None try: output = next(generator) message = "" for fragment in output.decode().split("\r\n"): if fragment: msg = json.loads(fragment) if "stream" in msg: msg = msg["stream"] match = re.search( r"(^Successfully built |sha256:)([0-9a-f]+)$", msg) if match: image_id = match.group(2) else: msg = fragment message += msg message = "".join(message).strip("\n") reporter.verbosity1(message) except StopIteration: reporter.info("Docker image build complete.") break except ValueError: # pragma: no cover reporter.error( "Error parsing output from docker image build: {}".format( output)) # pragma: no cover if image_id is None: raise InvocationError("docker image build failed") # pragma: no cover _BUILT_IMAGES.add(image_id) return image_id
def info(self, name, msg): reporter.verbosity1("{} {}: {}".format(self.name, name, msg), bold=True)
def finish(self): previous_config = CreationConfig.readconfig(self.path_config) live_config = self._getliveconfig() if previous_config is None or not previous_config.matches(live_config): content = live_config.writeconfig(self.path_config) reporter.verbosity1("write config to {} as {!r}".format(self.path_config, content))
def msg(path, what): reporter.verbosity1( "PEP-514 violation in Windows Registry at {} error: {}".format( path, what))
def stop_container(container): reporter.verbosity1(f"stop container via {container.short_id} ({container.attrs['Name']})") container.stop(timeout=0) container.remove()
def setactivity(self, name, msg): self.activity = name if msg: reporter.verbosity0("{} {}: {}".format(self.name, name, msg), bold=True) else: reporter.verbosity1("{} {}: {}".format(self.name, name, msg), bold=True)