blob: d1100606ceca353ac9908406857bd8392bb4dfb1 [file]
# Licensed to the Apache Software Foundation (ASF) under one
# or more contributor license agreements. See the NOTICE file
# distributed with this work for additional information
# regarding copyright ownership. The ASF licenses this file
# to you 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.
"""Install TOML dependency groups on old Python/pip without --group support.
Modern development environments use ``pip install -e . --group dev`` directly.
This bridge reads the same configuration for the Python 3.6/3.7 CI lanes.
"""
import argparse
import os
import re
import subprocess
import sys
try:
import tomllib
except ImportError:
import tomli as tomllib
def _normalize(name):
return re.sub(r"[-_.]+", "-", name).lower()
def resolve_group(groups, name, parents=()):
name = _normalize(name)
if name in parents:
raise ValueError("Cyclic dependency group: {}".format(name))
requirements = []
for item in groups[name]:
if isinstance(item, str):
requirements.append(item)
elif isinstance(item, dict) and set(item) == {"include-group"}:
requirements.extend(resolve_group(
groups, item["include-group"], parents + (name,)))
else:
raise ValueError("Invalid dependency group item: {!r}".format(item))
return requirements
def main():
parser = argparse.ArgumentParser(description=__doc__)
parser.add_argument("group")
args = parser.parse_args()
root = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
with open(os.path.join(root, "pyproject.toml"), "rb") as project_file:
raw_groups = tomllib.load(project_file)["dependency-groups"]
groups = {_normalize(name): value for name, value in raw_groups.items()}
if len(groups) != len(raw_groups):
raise ValueError("Duplicate normalized dependency group names")
subprocess.check_call(
[sys.executable, "-m", "pip", "install", root] +
resolve_group(groups, args.group))
if __name__ == "__main__":
main()