-
Notifications
You must be signed in to change notification settings - Fork 89
/
Copy pathtesseract_installer.py
172 lines (136 loc) · 6.41 KB
/
tesseract_installer.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
#!/usr/bin/env python3
# Testing locally
# docker run -it -v ~/catkin_ws:/home/catkin_ws --env DEBIAN_FRONTEND=noninteractive ubuntu:jammy bash
# apt update && apt install -y python3 python3-pip curl unzip sudo
# pip3 install requests
# apt install -y --no-install-recommends software-properties-common
# add-apt-repository -y ppa:levi-armstrong/tesseract-robotics
# apt update && apt install -y libompl-dev taskflow
# python3 tesseract_installer.py 0.28 jammy
# export TESSERACT_RESOURCE_PATH=/usr/share/tesseract_support:/usr/share/tesseract_task_composer
import requests
import os
import subprocess
import argparse
# List of GitHub API URLs for the upstream repositories
UPSTREAM_DEPENDS_URLS = [
"https://api.github.com/repos/ros-industrial/ros_industrial_cmake_boilerplate/releases/tags/0.7.2",
"https://api.github.com/repos/ethz-adrl/ifopt/releases/tags/2.1.4",
"https://api.github.com/repos/Jmeyer1292/opw_kinematics/releases/tags/0.5.2",
"https://api.github.com/repos/swri-robotics/descartes_light/releases/tags/0.4.6",
]
# List of GitHub API URLs for the repositories
REPO_API_URLS = [
"https://api.github.com/repos/tesseract-robotics/tesseract/releases",
"https://api.github.com/repos/tesseract-robotics/trajopt/releases",
"https://api.github.com/repos/tesseract-robotics/tesseract_planning/releases",
"https://api.github.com/repos/tesseract-robotics/tesseract_qt/releases",
]
TOKEN = os.getenv("GITHUB_TOKEN") # Optional: GitHub personal access token
def fetch_latest_patch(tag_version_prefix, api_url, token=None):
headers = {"Authorization": f"token {token}"} if token else {}
response = requests.get(api_url, headers=headers)
response.raise_for_status()
releases = response.json()
# Find the latest release matching the tag prefix
for release in releases:
if release["tag_name"].startswith(tag_version_prefix):
return release
raise ValueError(f"No release found for prefix {tag_version_prefix} in {api_url}")
def fetch_assets(release):
return release.get("assets", [])
def download_file(url, output_path):
response = requests.get(url, stream=True)
response.raise_for_status()
with open(output_path, "wb") as f:
for chunk in response.iter_content(chunk_size=8192):
f.write(chunk)
def install_debs_from_zip(zip_file):
print(f"Extracting {zip_file}...")
subprocess.run(["unzip", "-o", zip_file], check=True)
print(f"Installing all .deb files from {zip_file}...")
deb_files = [file for file in os.listdir() if file.endswith(".deb")]
if deb_files:
try:
# Step 1: Attempt to install all .deb files
print(f"Running dpkg to install the following .deb files: {deb_files}")
subprocess.run(["sudo", "dpkg", "-i"] + deb_files, check=True)
except subprocess.CalledProcessError:
print("dpkg encountered dependency issues. Attempting to resolve...")
# Step 2: Resolve dependencies
print("Resolving missing dependencies with apt-get -f install...")
subprocess.run(["sudo", "env", "DEBIAN_FRONTEND=noninteractive", "apt", "-f", "install", "-y"], check=True)
# Step 3: Reconfigure packages to ensure all are configured
print("Reconfiguring packages to complete the installation...")
subprocess.run(["sudo", "dpkg", "--configure", "-a"], check=True)
# Clean up .deb files
for file in deb_files:
os.remove(file)
else:
print(f"No .deb files found in {zip_file}.")
os.remove(zip_file)
def main(tag_version_prefix, distro_name):
for api_url in UPSTREAM_DEPENDS_URLS:
print(f"Processing repository: {api_url}")
try:
# Get the release
headers = {"Authorization": f"token {TOKEN}"} if TOKEN else {}
response = requests.get(api_url, headers=headers)
response.raise_for_status()
release_data = response.json()
# Fetch assest
assets = fetch_assets(release_data)
# Filter assets based on distribution name
filtered_assets = [
asset for asset in assets if f"debian_package_{distro_name}.zip" in asset["name"]
]
if not filtered_assets:
print(f"No matching assets found for {distro_name} in {api_url}.")
continue
for asset in filtered_assets:
name = asset["name"]
download_url = asset["browser_download_url"]
print(f"Downloading {name}...")
download_file(download_url, name)
install_debs_from_zip(name)
print(f"Finished processing repository: {api_url}")
except Exception as e:
print(f"Error processing repository {api_url}: {e}")
for api_url in REPO_API_URLS:
print(f"Processing repository: {api_url}")
try:
latest_release = fetch_latest_patch(tag_version_prefix, api_url, TOKEN)
print(f"Latest release found: {latest_release['tag_name']}")
assets = fetch_assets(latest_release)
# Filter assets based on distribution name
filtered_assets = [
asset for asset in assets if f"debian_package_{distro_name}.zip" in asset["name"]
]
if not filtered_assets:
print(f"No matching assets found for {distro_name} in {api_url}.")
continue
for asset in filtered_assets:
name = asset["name"]
download_url = asset["browser_download_url"]
print(f"Downloading {name}...")
download_file(download_url, name)
install_debs_from_zip(name)
print(f"Finished processing repository: {api_url}")
except Exception as e:
print(f"Error processing repository {api_url}: {e}")
print("All repositories processed!")
if __name__ == "__main__":
parser = argparse.ArgumentParser(
description="Download and install Debian artifacts from multiple GitHub releases for a version prefix."
)
parser.add_argument(
"tag_version_prefix",
help="The version prefix (e.g., 0.28) to fetch the latest patch for all repositories.",
)
parser.add_argument(
"distro_name",
choices=["focal", "jammy", "noble"],
help="The distribution name to filter assets (e.g., focal, jammy, noble).",
)
args = parser.parse_args()
main(args.tag_version_prefix, args.distro_name)