| #!/usr/bin/env python |
| # Copyright 2016 The Fuchsia Authors. All rights reserved. |
| # Use of this source code is governed by a BSD-style license that can be |
| # found in the LICENSE file. |
| |
| import argparse |
| import os |
| import string |
| import sys |
| |
| def parse_dot_packages(dot_packages_path): |
| deps = {} |
| with open(dot_packages_path) as dot_packages: |
| for line in dot_packages: |
| if line.startswith('#'): |
| continue |
| delim = line.find(':file://') |
| if delim == -1: |
| continue |
| name = line[:delim] |
| path = os.path.abspath(line[delim + 8:].strip()) |
| if name in deps: |
| raise Exception('%s contains multiple entries for package %s' % |
| (dot_packages_path, name)) |
| deps[name] = path |
| return deps |
| |
| |
| def create_base_directory(file): |
| path = os.path.dirname(file) |
| if not os.path.exists(path): |
| os.makedirs(path) |
| |
| |
| def main(): |
| parser = argparse.ArgumentParser( |
| "Generate .packages file for dart package") |
| parser.add_argument("--out", help="Path to .packages file to generate", |
| required=True) |
| parser.add_argument("--root-build-dir", |
| help="Path to root of the build directory", required=True) |
| parser.add_argument("--root-gen-dir", |
| help="Path to root of the gen directory", required=True) |
| parser.add_argument("--package-name", help="Name of this package", |
| required=True) |
| parser.add_argument("--source-dir", help="Path to package source", |
| required=True) |
| parser.add_argument( |
| "--depfile", help="Location of depfile to generate", required=True) |
| parser.add_argument("--deps", help="List of dependencies", nargs="*") |
| args = parser.parse_args() |
| |
| # Note: args.out will start with a toolchain subdirectory when applicable. |
| # Not using args.root_gen_dir exclusively as depfile needs to use target paths |
| # relative to args.root_build_dir. |
| dot_packages_file = os.path.join(args.root_build_dir, args.out) |
| create_base_directory(dot_packages_file) |
| |
| dependent_files = [] |
| |
| package_deps = {} |
| package_deps[args.package_name] = args.source_dir |
| for dep in args.deps: |
| if not dep.startswith("//"): |
| print "Error, expected dependency label to start with //" |
| return 1 |
| target_base = dep[2:] |
| target_sep = string.rfind(target_base, ":") |
| if target_sep != -1: |
| target_name = target_base[target_sep+1:] |
| target_base = target_base[:target_sep] |
| else: |
| target_name = target_base[target_base.rfind("/")+1:] |
| # Note: args.root_gen_dir takes the toolchain into account, so we know we |
| # only depend on packages "built" for the same toolchain. |
| dep_dot_packages_path = os.path.join( |
| args.root_gen_dir, target_base, "%s.packages" % target_name) |
| dependent_files.append(dep_dot_packages_path) |
| dependent_packages = parse_dot_packages(dep_dot_packages_path) |
| for name, path in dependent_packages.iteritems(): |
| if name in package_deps: |
| if path != package_deps[name]: |
| print "Error, conflicting entries for %s: %s and %s from %s" % (name, |
| path, package_deps[name], dep) |
| return 1 |
| else: |
| package_deps[name] = path |
| |
| with open(dot_packages_file, "w") as dot_packages: |
| names = package_deps.keys() |
| names.sort() |
| for name in names: |
| dot_packages.write('%s:file://%s/\n' % (name, package_deps[name])) |
| |
| with open(args.depfile, "w") as depfile: |
| depfile.write("%s: %s\n" % (args.out, " ".join(dependent_files))) |
| |
| return 0 |
| |
| if __name__ == '__main__': |
| sys.exit(main()) |