Skip to content
This repository has been archived by the owner on Feb 4, 2020. It is now read-only.

add support for package format 3 #168

Merged
merged 2 commits into from
Nov 14, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
43 changes: 37 additions & 6 deletions ament_tools/topological_order.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
# limitations under the License.

import copy
import os

from .packages import find_unique_packages as _find_unique_packages

Expand Down Expand Up @@ -42,12 +43,22 @@ def calculate_depends_for_topological_order(self, packages):
:param packages: dict of name to ``_PackageDecorator``
"""
self.depends_for_topological_order = set()
# skip external dependencies, meaning names that are not known packages
# collect all direct dependencies
deps = (self.package.build_depends +
self.package.buildtool_depends +
self.package.exec_depends +
self.package.test_depends)
for name in [d.name for d in deps if d.name in packages.keys()]:
names = [d.name for d in deps if d.evaluated_condition]

# collect all group dependencies
for group_depend in self.package.group_depends:
if group_depend.evaluated_condition:
assert group_depend.members is not None, \
'Group members need to be determined before'
names += group_depend.members

# skip external dependencies, meaning names that are not known packages
for name in [n for n in names if n in packages.keys()]:
packages[name]._add_recursive_run_depends(
packages, self.depends_for_topological_order)

Expand All @@ -73,10 +84,17 @@ def _add_recursive_run_depends(
deps = (self.package.build_export_depends +
self.package.buildtool_export_depends +
self.package.exec_depends)
for name in [d.name
for d in deps
if (d.name in package_names and
d.name not in depends_for_topological_order)]:
names = [d.name for d in deps if d.evaluated_condition]

for group_depend in self.package.group_depends:
if group_depend.evaluated_condition:
assert group_depend.members is not None, \
'Group members need to be determined before'
names += group_depend.members

for name in [n for n in names
if (n in package_names and
n not in depends_for_topological_order)]:
packages[name]._add_recursive_run_depends(
packages, depends_for_topological_order)

Expand Down Expand Up @@ -125,6 +143,11 @@ def topological_order_packages(
"""
Order packages topologically.

evaluate_conditions() will be called for each package.

If group dependencies haven't determined their members yet
extract_group_members() will be called for each group dependency to do so.

Return packages based on direct build, buildtool, and test dependencies and
recursive build_export, buildtool_export, and exec dependencies.

Expand Down Expand Up @@ -167,6 +190,14 @@ def topological_order_packages(
package, path)
decorators_by_name.update(underlay_decorators_by_name)

# evaluate conditions and determine group membership
pkgs = [d.package for d in decorators_by_name.values()]
for pkg in pkgs:
pkg.evaluate_conditions(os.environ)
for group_depend in pkg.group_depends:
if group_depend.evaluated_condition:
group_depend.extract_group_members(pkgs)

# calculate transitive dependencies
for decorator in decorators_by_name.values():
decorator.calculate_depends_for_topological_order(decorators_by_name)
Expand Down
7 changes: 5 additions & 2 deletions ament_tools/verbs/build/cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -273,9 +273,12 @@ def iterate_packages(opts, packages, per_package_callback):
package_opts.build_dependencies.append(package_share)

# get the package share folder for each exec depend of the package
# also consider group dependencies
package_opts.exec_dependency_paths_in_workspace = []
for dep_object in package.exec_depends:
dep_name = dep_object.name
dep_names = [d.name for d in package.exec_depends]
for g in package.group_depends:
dep_names += g.members
for dep_name in dep_names:
if dep_name not in workspace_package_names:
# do not add to this list if the dependency is not in the workspace
continue
Expand Down
28 changes: 25 additions & 3 deletions ament_tools/verbs/list_dependencies.py
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,11 @@ def prepare_arguments(parser):
action='store_true',
help='Show only test dependencies of a given package',
)
parser.add_argument(
'--group-deps',
action='store_true',
help='Show only group dependencies of a given package',
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This option is good, but if I interpret the usage of it correctly, it only shows you that a given package has a group dependency and the name of the group. It does not tell you which packages in the workspace are considered a member of that group.

So, it would be good to either expand the group dependency and display them as part of this option or have an option like list --group-of <group name>.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Makes sense. dc26ceb lists all member of the group.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That looks good to me, 👍.

)
parser.add_argument(
'package',
metavar='PACKAGE',
Expand All @@ -55,16 +60,20 @@ def prepare_arguments(parser):


def main(options):
deps = []
packages = find_packages(options.basepath)
# show all dependencies if no options are given
if not (options.build_deps or options.doc_deps or options.run_deps or options.test_deps):
if not (
options.build_deps or options.doc_deps or options.run_deps or
options.test_deps or options.group_deps
):
options.build_deps = True
options.doc_deps = True
options.run_deps = True
options.test_deps = True
options.group_deps = True
for (path, package) in packages.items():
if package.name == options.package:
deps = []
if options.build_deps:
deps.extend(package.build_depends + package.buildtool_depends)
if options.doc_deps:
Expand All @@ -76,8 +85,21 @@ def main(options):
package.exec_depends)
if options.test_deps:
deps.extend(package.test_depends)
# evaluate conditions
package.evaluate_conditions(os.environ)
# reduce dependencies to their names
deps = [d.name for d in deps if d.evaluated_condition]
# extract group memberships
if options.group_deps:
for g in package.group_depends:
if not g.evaluated_condition:
continue
g.extract_group_members(packages.values())
deps.append(
'%s (group members: %s)' %
(g.name, ', '.join(sorted(g.members))))
# Remove duplicate entries, sort output
for line in sorted(set(map(lambda dep: dep.name, deps))):
for line in sorted(set(deps)):
print(line)
return
print('No package with name {!r} found'.format(options.package), file=sys.stderr)
Expand Down
26 changes: 20 additions & 6 deletions ament_tools/verbs/list_packages.py
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ def prepare_arguments(parser):


def get_unique_depend_names(package):
return list({
names = {
d.name for d in
package.build_depends +
package.buildtool_depends +
Expand All @@ -64,27 +64,41 @@ def get_unique_depend_names(package):
package.exec_depends +
package.test_depends +
package.doc_depends
})
if d.evaluated_condition
}
for g in package.group_depends:
if g.evaluated_condition:
names |= set(g.members)
return names


def main(options):
lines = []
if not options.topological_order:
package_paths = find_package_paths(options.basepath)
# parse package manifests
packages = {}
for package_path in package_paths:
package = None
package_abs_path = os.path.join(options.basepath, package_path)
package = parse_package(package_abs_path)
packages[package_path] = package
# evaluate conditions
for package in packages.values():
package.evaluate_conditions(os.environ)
# expand group dependencies
for package in packages.values():
for group in package.group_depends:
if group.evaluated_condition:
group.extract_group_members(packages.values())
for package_path, package in packages.items():
if options.depends_on is not None:
package = parse_package(package_abs_path)
if options.depends_on not in get_unique_depend_names(package):
continue
if options.names_only:
package = package or parse_package(package_abs_path)
lines.append(package.name)
elif options.paths_only:
lines.append(package_path)
else:
package = package or parse_package(package_abs_path)
lines.append(package.name + ' ' + package_path)
lines.sort()
else:
Expand Down