Skip to content

Commit

Permalink
WIP oe
Browse files Browse the repository at this point in the history
  • Loading branch information
andre-rosa committed Mar 7, 2019
1 parent b2b928d commit 307fbb6
Show file tree
Hide file tree
Showing 13 changed files with 334 additions and 69 deletions.
57 changes: 57 additions & 0 deletions .vscode/launch.json
@@ -0,0 +1,57 @@
{
// Use IntelliSense to learn about possible attributes.
// Hover to view descriptions of existing attributes.
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
"version": "0.2.0",
"configurations": [
{
"name": "superflore-gen-meta-pkgs",
"type": "python",
"request": "launch",
"program": "${env:HOME}/.local/bin/superflore-gen-meta-pkgs",
"stopOnEntry": true,
"console": "none",
"cwd": "${workspaceFolder}",
"env": {
"SUPERFLORE_GITHUB_TOKEN": "",
"ROSDEP_DEBUG": "true"
},
"args": [
"--dry-run",
"--ros-distro",
"bouncy",
]
},
{
"name": "superflore-check-ebuilds",
"type": "python",
"request": "launch",
"program": "${env:HOME}/.local/bin/superflore-check-ebuilds",
"stopOnEntry": true,
"console": "none",
"cwd": "${workspaceFolder}",
"env": {
"SUPERFLORE_GITHUB_TOKEN": ""
},
"args": [
]
},
{
"name": "superflore-gen-ebuilds",
"type": "python",
"request": "launch",
"program": "${env:HOME}/.local/bin/superflore-gen-ebuilds",
"stopOnEntry": true,
"console": "none",
"cwd": "${workspaceFolder}",
"env": {
"SUPERFLORE_GITHUB_TOKEN": ""
},
"args": [
"--dry-run",
"--ros-distro",
"crystal"
]
},
]
}
4 changes: 4 additions & 0 deletions .vscode/settings.json
@@ -0,0 +1,4 @@
{
"python.pythonPath": "env/bin/python",
"python.linting.pylintEnabled": true
}
3 changes: 2 additions & 1 deletion setup.py
Expand Up @@ -18,7 +18,8 @@
'docker',
'pyyaml',
'pygithub',
'catkin_pkg >= 0.4.0'
'catkin_pkg >= 0.4.0',
'bs4'
]

setup(
Expand Down
3 changes: 2 additions & 1 deletion superflore/TempfileManager.py
Expand Up @@ -44,7 +44,8 @@ def __exit__(self, *args):
if self.temp_path:
info("Cleaning up temporary directory %s" % self.temp_path)
try:
shutil.rmtree(self.temp_path)
#shutil.rmtree(self.temp_path)
pass
except OSError as ex:
if ex.errno == errno.EPERM:
err("Failed to rmtree %s" % self.temp_path)
Expand Down
21 changes: 12 additions & 9 deletions superflore/generators/bitbake/gen_packages.py
Expand Up @@ -71,7 +71,7 @@ def regenerate_installer(
for f in glob.glob('%s*.patch' % patch_path)
]
if preserve_existing and existing:
ok("recipe for package '%s' up to date, skpping..." % pkg)
ok("recipe for package '%s' up to date, skipping..." % pkg)

This comment has been minimized.

Copy link
@allenh1

allenh1 Mar 14, 2019

haha, oops.

return None, []
elif existing:
overlay.repo.remove_file(existing[0])
Expand All @@ -88,10 +88,10 @@ def regenerate_installer(
except UnresolvedDependency:
dep_err = 'Failed to resolve required dependencies for'
err("{0} package {1}!".format(dep_err, pkg))
unresolved = current.recipe.get_unresolved()
unresolved = current.recipe.get_unresolved_cache()
for dep in unresolved:
err(" unresolved: \"{}\"".format(dep))
return None, current.recipe.get_unresolved()
return None, unresolved
except NoPkgXml:
err("Could not fetch pkg!")
return None, []
Expand All @@ -107,14 +107,15 @@ def regenerate_installer(
)
success_msg = 'Successfully generated installer for package'
ok('{0} \'{1}\'.'.format(success_msg, pkg))
recipe_name = '{0}/recipes-ros-{1}/{2}/{2}_{3}.bb'.format(
recipe_file_name = '{0}/recipes-ros-{1}/{2}/{2}_{3}.bb'.format(
overlay.repo.repo_dir,
distro.name,
pkg.replace('_', '-'),
version
)
try:
with open('{0}'.format(recipe_name), "w") as recipe_file:
with open('{0}'.format(recipe_file_name), "w") as recipe_file:
ok('Writing recipe {0}'.format(recipe_file_name))
recipe_file.write(recipe_text)
except Exception as e:
err("Failed to write recipe to disk!")
Expand All @@ -126,6 +127,7 @@ def _gen_recipe_for_package(
distro, pkg_name, pkg, repo, ros_pkg,
pkg_rosinstall, tar_dir, md5_cache, sha256_cache, patches, incs
):
pkg_names = get_package_names(distro)
pkg_dep_walker = DependencyWalker(distro)
pkg_buildtool_deps = pkg_dep_walker.get_depends(pkg_name, "buildtool")
pkg_build_deps = pkg_dep_walker.get_depends(pkg_name, "build")
Expand All @@ -144,17 +146,17 @@ def _gen_recipe_for_package(
)
# add run dependencies
for rdep in pkg_run_deps:
pkg_recipe.add_depend(rdep)
pkg_recipe.add_build_depend(rdep, rdep in pkg_names[0])

# add build dependencies
for bdep in pkg_build_deps:
pkg_recipe.add_depend(bdep)
pkg_recipe.add_build_depend(bdep, bdep in pkg_names[0])

# add build tool dependencies
for tdep in pkg_buildtool_deps:
pkg_recipe.add_depend(tdep)
pkg_recipe.add_build_depend(tdep, tdep in pkg_names[0])

# parse throught package xml
# parse through package xml
try:
pkg_xml = ros_pkg.get_package_xml(distro.name)
except Exception:
Expand All @@ -165,6 +167,7 @@ def _gen_recipe_for_package(
pkg_recipe.license = pkg_fields.upstream_license
pkg_recipe.description = pkg_fields.description
pkg_recipe.homepage = pkg_fields.homepage
pkg_recipe.build_type = pkg_fields.build_type
return pkg_recipe


Expand Down
128 changes: 128 additions & 0 deletions superflore/generators/bitbake/oe_query.py
@@ -0,0 +1,128 @@
import urllib
import bs4

from collections import OrderedDict


class OpenEmbeddedLayersDB(object):
def __init__(self):
# Tells if we could read recipe information
self._exists = False
# Valid layers in priority order to filter when searching for a recipe
self._prio_valid_layers = OrderedDict.fromkeys(['openembedded-core', 'meta-oe', 'meta-python', 'meta-multimedia',
'meta-ros', 'meta-intel-realsense', 'meta-qt5', 'meta-clang', 'meta-sca', 'meta-openstack', 'meta-virtualization'])
# All fields below come straight from OpenEmbedded Layer query table results
self.name = ''
self.version = ''
self.summary = ''
self.description = ''
self.section = ''
self.license = ''
self.homepage = ''
self.recipe = ''
self.layer = ''
self.inherits = ''
self.dependencies = ''
self.packageconfig = ''

def __str__(self):
if not self._exists:
return ''
return '\n'.join([getattr(self, i) for i in vars(self) if not i.startswith('_')])

def _fill_field(self, key, value):
if key:
my_attr = '{}'.format(key.split()[0].lower())
if hasattr(self, my_attr):
setattr(self, my_attr, value)
return True
return False

def _get_first_on_multiple_matches(self, bs):
class QueryResult:
def __init__(self):
self.recipe_name = ''
self.link = ''
self.version = ''
self.description = ''
self.layer = ''

def __str__(self):
return '\n'.join([self.recipe_name, self.link, self.version, self.description, self.layer])

if bs.table.find('th', text='Recipe name'):
tr = bs.table.find('tr')
while tr:
td = tr.find('td')
tr = tr.findNext('tr')
if not td:
continue
qr = QueryResult()
for f in ['recipe_name', 'version', 'description', 'layer']:
if f == 'recipe_name':
a = td.find('a')
if a:
setattr(qr, 'link', str(
"https://layers.openembedded.org" + a.get('href', '')))
setattr(qr, f, str(td.text))
td = td.find_next_sibling()
if not td:
break
if qr.link:
# Get first valid entry
self._query_url(qr.link)
return

def _query_url(self, query_url):
try:
req = urllib.request.urlopen(query_url)
read_str = req.read()
bs = bs4.BeautifulSoup(read_str, "html.parser")
th = bs.table.find('th', text='Name')
while th:
td = th.findNext('td')
if td:
self._exists |= self._fill_field(
str(th.text), str(td.text))
th = th.findNext('th')
except Exception:
self._exists = False
return
if not self._exists and bs:
# Didn't match fully, so search on multi-match table
self._get_first_on_multiple_matches(bs)
else:
# Confirm that the only recipe found is indeed in a valid layer
for layer in self._prio_valid_layers:
if self.layer.startswith(layer):
return
self._exists = False

def exists(self):
return self._exists

def query_recipe(self, recipe):
if recipe:
url_prefix = 'https://layers.openembedded.org/layerindex/branch/master/recipes/?q={}'
for layer in self._prio_valid_layers:
query_url = url_prefix.format(
recipe + urllib.parse.quote(' layer:') + layer)
self._query_url(query_url)
if self.exists():
return


def main():
for recipe in ['', 'clang', 'ament_cmake_core', 'ament-cmake-core', 'libxml2', 'bullet', 'sdl', 'sdl-image', 'qtbase']:
print('Checking ' + recipe + '...')
oe_query = OpenEmbeddedLayersDB()
oe_query.query_recipe(recipe)
if oe_query.exists():
print(oe_query)
else:
print("Recipe {} doesn't exist!".format(recipe))
print()


if __name__ == "__main__":
main()
3 changes: 3 additions & 0 deletions superflore/generators/bitbake/ros_meta.py
Expand Up @@ -46,6 +46,9 @@ def commit_changes(self, distro):
'lunar': 'regenerate ros-lunar, {0}',
'indigo': 'regenerate ros-indigo, {0}',
'kinetic': 'regenerate ros-kinetic, {0}',
'ardent': 'regenerate ros-ardent, {0}',
'bouncy': 'regenerate ros-bouncy, {0}',
'crystal': 'regenerate ros-crystal, {0}',
}[distro].format(time.ctime())
info('Committing to branch {0}...'.format(self.branch_name))
self.repo.git.commit(m='{0}'.format(commit_msg))
Expand Down
14 changes: 9 additions & 5 deletions superflore/generators/bitbake/run.py
Expand Up @@ -20,6 +20,7 @@
from superflore.generate_installers import generate_installers
from superflore.generators.bitbake.gen_packages import regenerate_installer
from superflore.generators.bitbake.ros_meta import RosMeta
from superflore.generators.bitbake.yocto_recipe import yoctoRecipe
from superflore.parser import get_parser
from superflore.repo_instance import RepoInstance
from superflore.TempfileManager import TempfileManager
Expand All @@ -40,6 +41,7 @@


def main():
os.environ["ROS_OS_OVERRIDE"] = "oe"
preserve_existing = True
overlay = None
parser = get_parser('Deploy ROS packages into Yocto Linux')
Expand Down Expand Up @@ -73,8 +75,8 @@ def main():
err('Failed to file PR!')
err('reason: {0}'.format(e))
sys.exit(1)
repo_org = 'allenh1'
repo_name = 'meta-ros'
repo_org = 'andre-rosa'
repo_name = 'meta-ros2'
if args.upstream_repo:
repo_org, repo_name = url_to_repo_org(args.upstream_repo)
# open cached tar file if it exists
Expand All @@ -92,7 +94,7 @@ def main():
if not args.only:
pr_comment = pr_comment or (
'Superflore yocto generator began regeneration of all '
'packages form ROS distribution(s) %s on Meta-ROS from '
'packages from ROS distribution(s) %s on Meta-ROS from '
'commit %s.' % (
selected_targets,
overlay.repo.get_last_hash()
Expand All @@ -101,7 +103,7 @@ def main():
else:
pr_comment = pr_comment or (
'Superflore yocto generator began regeneration of package(s)'
' %s from ROS distro %s from Meta-ROS from commit %s.' % (
' %s from ROS distribution(s) %s on Meta-ROS from commit %s.' % (
args.only,
args.ros_distro,
overlay.repo.get_last_hash()
Expand All @@ -111,6 +113,8 @@ def main():
total_installers = dict()
total_broken = set()
total_changes = dict()
yoctoRecipe.reset_resolved_cache()
yoctoRecipe.reset_unresolved_cache()
if args.tar_archive_dir:
sha256_filename = '%s/sha256_cache.pickle' % args.tar_archive_dir
md5_filename = '%s/md5_cache.pickle' % args.tar_archive_dir
Expand Down Expand Up @@ -141,7 +145,7 @@ def main():
regen_dict[args.ros_distro] = args.only
overlay.commit_changes(args.ros_distro)
if args.dry_run:
save_pr(overlay, args.only, pr_comment)
save_pr(overlay, args.only, '', pr_comment)
sys.exit(0)
delta = "Regenerated: '%s'\n" % args.only
file_pr(overlay, delta, '', pr_comment, distro=args.ros_distro)
Expand Down

0 comments on commit 307fbb6

Please sign in to comment.