def tox_configure(config): def getfloat(reader, key): val = reader.getstring(key) if val is None: return None try: return float(val) except ValueError: msg = "{!r} is not a number (for {} in [{}])".format( val, key, reader.section_name) raise ValueError(msg) def gettime(reader, key): return int(getfloat(reader, key) * NANOSECONDS) def getint(reader, key): raw = getfloat(reader, key) val = int(raw) if val != raw: msg = "{!r} is not an int (for {} in [{}])".format( val, key, reader.section_name) raise ValueError(msg) return val inipath = str(config.toxinipath) iniparser = py.iniconfig.IniConfig(inipath) image_configs = {} for section in iniparser.sections: if not section.startswith("docker:"): continue reader = SectionReader(section, iniparser) _, _, image = section.partition(":") image_configs[image] = { "healthcheck_cmd": reader.getargv("healthcheck_cmd"), "healthcheck_interval": gettime(reader, "healthcheck_interval"), "healthcheck_timeout": gettime(reader, "healthcheck_timeout"), "healthcheck_retries": getint(reader, "healthcheck_retries"), "healthcheck_start_period": gettime(reader, "healthcheck_start_period"), } config._docker_image_configs = image_configs
def get_reader(self, section, prefix=None): """Creates a SectionReader and configures it with known and reasonable substitution values based on the config. :param section: Config section name to read from :param prefix: Any applicable prefix to the ini section name. Default None""" reader = SectionReader(section, self.config._cfg, prefix=prefix) distshare_default = "hotexamples_com/.tox/distshare" reader.addsubstitutions(toxinidir=self.config.toxinidir, homedir=self.config.homedir, toxworkdir=self.config.toxworkdir) self.config.distdir = reader.getpath("distdir", "{toxworkdir}/dist") reader.addsubstitutions(distdir=self.config.distdir) self.config.distshare = reader.getpath("distshare", distshare_default) reader.addsubstitutions(distshare=self.config.distshare) return reader
def getfloat(reader: SectionReader, key: str) -> Optional[float]: val = reader.getstring(key) if val is None: return None try: return float(val) except ValueError: msg = f"{val!r} is not a number (for {key} in [{reader.section_name}])" raise ValueError(msg)
def parse_container_config( config: Config, container_name: str, all_container_names: Container[str] ) -> ContainerConfig: inipath = str(config.toxinipath) iniparser = py.iniconfig.IniConfig(inipath) reader = SectionReader(f"docker:{container_name}", iniparser) reader.addsubstitutions( distdir=config.distdir, homedir=config.homedir, toxinidir=config.toxinidir, toxworkdir=config.toxworkdir, ) kwargs = { "name": container_name, "image": Image(reader.getstring("image")), "stop": container_name not in config.option.docker_dont_stop, } environment = None if reader.getstring("environment"): environment = getenvdict(reader, "environment") hc_cmd = hc_interval = hc_timeout = hc_start_period = hc_retries = None if reader.getstring("healthcheck_cmd"): hc_cmd = reader.getstring("healthcheck_cmd") if reader.getstring("healthcheck_interval"): hc_interval = gettime(reader, "healthcheck_interval") if reader.getstring("healthcheck_timeout"): hc_timeout = gettime(reader, "healthcheck_timeout") if reader.getstring("healthcheck_start_period"): hc_start_period = gettime(reader, "healthcheck_start_period") if reader.getstring("healthcheck_retries"): hc_retries = getint(reader, "healthcheck_retries") ports = None if reader.getstring("ports"): ports = [Port(line) for line in reader.getlist("ports")] links = None if reader.getstring("links"): links = [Link(line) for line in reader.getlist("links")] volumes = None if reader.getstring("volumes"): volumes = [Volume(line) for line in reader.getlist("volumes")] return ContainerConfig( name=container_name, image=Image(reader.getstring("image")), stop=container_name not in config.option.docker_dont_stop, environment=environment, healthcheck_cmd=hc_cmd, healthcheck_interval=hc_interval, healthcheck_timeout=hc_timeout, healthcheck_start_period=hc_start_period, healthcheck_retries=hc_retries, ports=ports, links=links, volumes=volumes, )
def getenvdict(reader: SectionReader, key: str) -> Mapping[str, str]: environment = {} for value in reader.getlist(key): envvar, _, value = value.partition("=") environment[envvar] = value return environment
def tox_configure(config): # noqa: C901 def getfloat(reader, key): val = reader.getstring(key) if val is None: return None try: return float(val) except ValueError: msg = f"{val!r} is not a number (for {key} in [{reader.section_name}])" raise ValueError(msg) def gettime(reader, key): return int(getfloat(reader, key) * SECOND) def getint(reader, key): raw = getfloat(reader, key) val = int(raw) if val != raw: msg = f"{val!r} is not an int (for {key} in [{reader.section_name}])" raise ValueError(msg) return val def getenvdict(reader, key): environment = {} for value in reader.getlist(key): envvar, _, value = value.partition("=") environment[envvar] = value return environment # discover container configs inipath = str(config.toxinipath) iniparser = py.iniconfig.IniConfig(inipath) container_configs = {} for section in iniparser.sections: if not section.startswith("docker:"): continue _, _, container_name = section.partition(":") if not re.match(r"^[a-zA-Z][-_.a-zA-Z0-9]+$", container_name): raise ValueError( f"{container_name!r} is not a valid container name") # populated in the next loop container_configs[container_name] = {} # validate command line options for container_name in config.option.docker_dont_stop: if container_name not in container_configs: raise ValueError( f"Container {container_name!r} not found (from --docker-dont-stop)" ) # validate tox.ini for section in iniparser.sections: if not section.startswith("docker:"): continue reader = SectionReader(section, iniparser) reader.addsubstitutions( distdir=config.distdir, homedir=config.homedir, toxinidir=config.toxinidir, toxworkdir=config.toxworkdir, ) _, _, container_name = section.partition(":") container_configs[container_name].update({ "image": reader.getstring("image"), "stop": container_name not in config.option.docker_dont_stop, }) if reader.getstring("environment"): env = getenvdict(reader, "environment") container_configs[container_name]["environment"] = env if reader.getstring("healthcheck_cmd"): container_configs[container_name][ "healthcheck_cmd"] = reader.getstring("healthcheck_cmd") if reader.getstring("healthcheck_interval"): container_configs[container_name][ "healthcheck_interval"] = gettime(reader, "healthcheck_interval") if reader.getstring("healthcheck_timeout"): container_configs[container_name]["healthcheck_timeout"] = gettime( reader, "healthcheck_timeout") if reader.getstring("healthcheck_start_period"): container_configs[container_name][ "healthcheck_start_period"] = gettime( reader, "healthcheck_start_period") if reader.getstring("healthcheck_retries"): container_configs[container_name]["healthcheck_retries"] = getint( reader, "healthcheck_retries") if reader.getstring("ports"): container_configs[container_name]["ports"] = reader.getlist( "ports") if reader.getstring("links"): container_configs[container_name]["links"] = dict( _validate_link_line(link_line, container_configs.keys()) for link_line in reader.getlist("links") if link_line.strip()) if reader.getstring("volumes"): container_configs[container_name]["mounts"] = [ _validate_volume_line(volume_line) for volume_line in reader.getlist("volumes") if volume_line.strip() ] config._docker_container_configs = container_configs
def add_factors(config, factors, position=AFTER): ini = config._cfg config_ini = _ParseIniWrapper(config, ini) for envname, envconfig in list(config.envconfigs.items()): newname = position(envname, factors) env_factors = envconfig.factors.copy() for factor in factors: env_factors.add(factor) reader = SectionReader(envname, ini, fallbacksections=["testenv"], factors=env_factors) reader.addsubstitutions(toxinidir=config.toxinidir, homedir=config.homedir) reader.addsubstitutions(toxworkdir=config.toxworkdir) reader.addsubstitutions(distdir=config.distdir) reader.addsubstitutions(distshare=config.distshare) if hasattr(config, "temp_dir"): reader.addsubstitutions(temp_dir=config.temp_dir) section = "{}{}".format(testenvprefix, envname) newenv = config_ini.make_envconfig(newname, section, reader._subs, config, replace=True) config.envconfigs[newname] = newenv # envlist if "TOXENV" in os.environ: os.environ["TOXENV"] = _add_to_each(os.environ["TOXENV"], factors, position) if config.option.env: config.option.env = [ _add_to_each(item, factors, position) for item in config.option.env ] config.envlist = [position(item, factors) for item in config.envlist] if hasattr(config, "envlist_default"): config.envlist_default = [ position(item, factors) for item in config.envlist_default ]