Skip to content

WIP: migrate tue-get to python #638

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

Draft
wants to merge 47 commits into
base: master
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
47 commits
Select commit Hold shift + click to select a range
ccce545
WIP: migrate tue-get to python
MatthijsBurgh Jan 3, 2023
956e4b8
WIP: migrate tue-get to python
MatthijsBurgh Jan 3, 2023
e7e53ae
Add *.egg-info to gitignore
MatthijsBurgh Jan 4, 2023
8fcab63
Make this a python module
MatthijsBurgh Jan 4, 2023
a22c95f
Add first version of pytests
MatthijsBurgh Jan 4, 2023
94ca54a
Most bash functions should be connected to python
MatthijsBurgh Jan 7, 2023
872cbc7
Sudo password is on stderr
MatthijsBurgh Jan 7, 2023
2347107
remove tue_install_impl.py; should be moved
MatthijsBurgh Jan 7, 2023
4c55516
Fix tue-install-pipe; does require echo of stdout for pipe
MatthijsBurgh Jan 7, 2023
7207cc9
Add tue-install-add-text
MatthijsBurgh Jan 7, 2023
2a0ca0a
Reorder deps
MatthijsBurgh Jan 8, 2023
98672cc
Workin tue-install-system-now
MatthijsBurgh Jan 8, 2023
4e8f187
Various improvements to tue-get
MatthijsBurgh Jan 8, 2023
da1d3e8
Add working tue-install-ppa-now
MatthijsBurgh Jan 8, 2023
7bdea75
Add grep funcs
MatthijsBurgh Jan 8, 2023
d13e0e6
Add working tue-install-snap-now
MatthijsBurgh Jan 8, 2023
2498ace
Add ?working? tue-install-dpkg-now
MatthijsBurgh Jan 8, 2023
c028f01
Add inspired by reference for istext funcs
MatthijsBurgh Jan 8, 2023
3664f65
Add working tue-install-pip-now
MatthijsBurgh Jan 8, 2023
e8d5cfc
Apply black
MatthijsBurgh Jan 8, 2023
29821bd
Fix yaml parser
MatthijsBurgh Jan 8, 2023
1608c3f
WIP tue-install-ros
MatthijsBurgh Jan 8, 2023
b473db0
Revert back to test target
MatthijsBurgh Jan 8, 2023
928cba2
Working tue-install-ros
MatthijsBurgh Jan 9, 2023
7aa35b7
Remove temp prints
MatthijsBurgh Jan 9, 2023
8baee29
Add tue-install-pip3(-now) for bash scripts
MatthijsBurgh Jan 9, 2023
2aa7977
Handle multiline bash logs correctly
MatthijsBurgh Jan 9, 2023
779d8e6
Various small bug fixes
MatthijsBurgh Jan 9, 2023
de5e76f
Temp prints as dummy funcs
MatthijsBurgh Jan 9, 2023
269f9db
Let tue-install-ppa do the string magic
MatthijsBurgh Jan 9, 2023
0a9aaa4
Apply black
MatthijsBurgh Jan 9, 2023
fb8421f
Fix tue-install-cp
MatthijsBurgh Jan 9, 2023
f9b68d3
Don't write to stdin of closed process
MatthijsBurgh Jan 9, 2023
4806537
Fix package.xml check
MatthijsBurgh Jan 9, 2023
7b1a832
Fix args generation of tue-install-target(-now)
MatthijsBurgh Jan 9, 2023
43a958b
Fix tue-install-warning not printing
MatthijsBurgh Jan 9, 2023
2d95076
Fix ros system pkg name
MatthijsBurgh Jan 9, 2023
4ef22d5
(tue-get dep) adapt to ros1/ros2 target
MatthijsBurgh Jan 9, 2023
5a7b5e8
Add working tue-install-git
MatthijsBurgh Jan 9, 2023
137b665
Remove incorrect typehinting
MatthijsBurgh Jan 9, 2023
0a23249
less verbose cmd printing
MatthijsBurgh Jan 9, 2023
f179e9d
Apply black
MatthijsBurgh Jan 9, 2023
94ceb3b
Remove unused comment
MatthijsBurgh Jan 10, 2023
e0e98b5
Fix tue-install-ros
MatthijsBurgh Jan 10, 2023
bd3786b
Fixed naming of python file
MatthijsBurgh Jan 13, 2023
29ac21d
Add remaining install logic
MatthijsBurgh Jan 13, 2023
2cb7eb9
Fix Black Linting
MatthijsBurgh Feb 14, 2023
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -2,3 +2,6 @@ env
.rsettings
bin
user/

# Python install files
*.egg-info
141 changes: 140 additions & 1 deletion installer/parse_install_yaml.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
#! /usr/bin/env python3

from typing import List, Mapping, Optional
from typing import Any, List, Mapping, Optional
from functools import partial
from os import environ
import sys
import yaml
Expand Down Expand Up @@ -254,5 +255,143 @@ def get_distro_item(item: Mapping, key: str, release_version: str, release_type:
return {"system_packages": system_packages, "commands": commands}


def installyaml_parser2(installer: Any, path: str, now: bool = False) -> Mapping:
with open(path) as f:
try:
install_items = yaml.load(f, yaml.CSafeLoader)
except AttributeError:
install_items = yaml.load(f, yaml.SafeLoader)
except (yaml.parser.ParserError, yaml.scanner.ScannerError) as e:
raise ValueError(f"Invalid yaml syntax: {e}")

if not isinstance(install_items, list):
raise ValueError("Root of install.yaml file should be a YAML sequence")

system_packages = []

commands = []

def get_distro_item(item: Mapping, key: str, release_version: str, release_type: str) -> Optional[str]:
if key in item:
value = item[key]
if value is None:
raise ValueError(f"'{key}' is defined, but has no value")
elif len(item) < 3 or "default" not in item:
raise ValueError(f"At least one distro and 'default' should be specified or none in install.yaml")
else:
for version in [release_version, "default"]:
if version in item:
value = item[version][key]
break

return value

# Combine now calls
now_cache = {
"system-now": [],
"pip-now": [],
"pip3-now": [],
"ppa-now": [],
"snap-now": [],
"gem-now": [],
}

for install_item in install_items:
command = None

try:
install_type = install_item["type"] # type: str

if install_type == "empty":
return {"system_packages": system_packages, "commands": commands}

elif install_type == "ros":
try:
source = get_distro_item(install_item, "source", ros_release, "ROS")
except ValueError as e:
raise ValueError(f"[{install_type}]: {e.args[0]}")

# Both release and default are allowed to be None
if source is None:
continue

source_type = source["type"]
if source_type == "git":
command = partial(getattr(installer, "tue_install_ros", "git", catkin_git(source)))
elif source_type == "system":
system_packages.append(f"ros-{ros_release}-{source['name']}")
command = partial(getattr(installer, "tue_install_ros", "system", catkin_git(source)))
else:
raise ValueError(f"Unknown ROS install type: '{source_type}'")

# Non ros targets that are packaged to be built with catkin
elif install_type == "catkin":
source = install_item["source"]

if not source["type"] == "git":
raise ValueError(f"Unknown catkin install type: '{source['type']}'")
command = partial(getattr(installer, "tue_install_ros", "git", catkin_git(source)))

elif install_type == "git":
command = partial(getattr(installer, "tue_install_git", "git", type_git(install_item)))

elif install_type in [
"target",
"system",
"pip",
"pip3",
"ppa",
"snap",
"gem",
"dpkg",
"target-now",
"system-now",
"pip-now",
"pip3-now",
"ppa-now",
"snap-now",
"gem-now",
]:
install_type = install_type.replace("-", "_")
if now and "now" not in install_type:
install_type += "_now"

try:
pkg_name = get_distro_item(install_item, "name", ubuntu_release, "Ubuntu")
except ValueError as e:
raise ValueError(f"[{install_type}]: {e.args[0]}")

# Both release and default are allowed to be None
if pkg_name is None:
continue

if "system" in install_type:
system_packages.append(pkg_name)

# Cache install types which accept multiple pkgs at once
if install_type in now_cache:
now_cache[install_type].append(pkg_name)
continue
command = partial(getattr(installer, f"tue_install_{install_type}", pkg_name))

else:
raise ValueError(f"Unknown install type: '{install_type}'")

except KeyError as e:
raise KeyError(f"Invalid install.yaml file: Key '{e}' could not be found.")

if not command:
raise ValueError("Invalid install.yaml file")

commands.append(command)

for install_type, pkg_list in now_cache.items():
if pkg_list:
command = partial(getattr(installer, f"tue_install_{install_type}", pkg_list))
commands.append(command)

return {"system_packages": system_packages, "commands": commands}


if __name__ == "__main__":
sys.exit(main())
2 changes: 1 addition & 1 deletion installer/tue-get-dep.bash
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ hash xmlstarlet 2> /dev/null || sudo apt-get install --assume-yes -qq xmlstarlet

function _show_dep
{
[[ "$1" == "ros" ]] && return 0
[[ "$1" == "ros" ]] || [[ "$1" == "ros1" ]] || [[ "$1" == "ros2" ]] && return 0

[[ "$ROS_ONLY" = "true" && "$1" != ros-* ]] && return 0

Expand Down
43 changes: 43 additions & 0 deletions setup.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
import os.path

from setuptools import find_packages
from setuptools import setup

with open(os.path.join(os.path.dirname(__file__), "VERSION"), "r") as f:
version = f.readline().strip()

print(find_packages(where="src"))

setup(
name="tue_env",
packages=find_packages(where="src"),
package_dir={"": "src"},
package_data={"tue_get": ["src/tue_get/resources/*"]},
include_package_data=True,
version=version,
author="Matthijs van der Burgh",
author_email="[email protected]",
maintainer="Matthijs van der Burgh",
maintainer_email="[email protected]",
url="https://github.com/tue-robotics/tue-env",
keywords=["catkin"],
classifiers=[
"Environment :: Console",
"Intended Audience :: Developers",
"Programming Language :: Python",
],
description="Plugin for catkin_tools to enable building workspace documentation.",
# entry_points={
# "catkin_tools.commands.catkin.verbs": [
# "document = catkin_tools_document:description",
# ],
# "catkin_tools.spaces": [
# "docs = catkin_tools_document.spaces.docs:description",
# ],
# },
python_version=">=3.8",
install_requires=[
"pyyaml",
"termcolor",
],
)
4 changes: 4 additions & 0 deletions src/tue_get/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
from . import catkin_package_parser
from . import install_yaml_parser
from . import installer_impl
from . import util
47 changes: 47 additions & 0 deletions src/tue_get/catkin_package_parser.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
from typing import List, Mapping, Optional, Tuple

from catkin_pkg.package import Dependency, Package, parse_package
import os


def catkin_package_parser(
path: str,
skip_normal_deps: bool = False,
test_deps: bool = False,
doc_deps: bool = False,
warnings: Optional[List[str]] = None,
context: Optional[Mapping] = None,
) -> Tuple[Package, List[Dependency]]:
if context is None:
context = os.environ
dep_types = []
if not skip_normal_deps:
dep_types.extend(
[
"build_depends",
"buildtool_depends",
"build_export_depends",
"buildtool_export_depends",
"exec_depends",
]
)

if test_deps:
dep_types.append("test_depends")

if doc_deps:
dep_types.append("doc_depends")

pkg = parse_package(path, warnings=warnings)
pkg.evaluate_conditions(context)

deps = []
for dep_type in dep_types:
dep_list = getattr(pkg, dep_type)
for dep in dep_list: # type: Dependency
if dep.evaluated_condition is None:
raise RuntimeError("Dependency condition is None")
if dep.evaluated_condition:
deps.append(dep)

return pkg, deps
Loading