blob: 5e320333936d1787b3c5c50f2c5445c447ac2dcd [file] [log] [blame]
#!/usr/bin/env python
# Copyright 2018 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.
# This script translates a Dart .packages file into a manifest
# suitable for consumption by the "extra" parameter of the package() template
# in //build/package.gni.
import argparse
import os
import string
import subprocess
import sys
import urlparse
# Returns the set of files touched by gen_snapshot.
def GenSnapshotDeps(args):
depfile_sources = None
cmd = [
args.gen_snapshot,
'--print_dependencies',
'--dependencies_only',
'--packages=' + args.dot_packages,
'--vm_snapshot_data=/dev/null',
'--isolate_snapshot_data=/dev/null',
]
for url_mapping in args.url_mapping:
cmd.append("--url_mapping=" + url_mapping)
cmd.append(args.main_dart)
try:
result = subprocess.check_output(cmd, stderr=subprocess.STDOUT)
except subprocess.CalledProcessError as e:
print ("gen_snapshot failed: " + ' '.join(cmd) + "\n" +
"output: " + e.output)
return 1
if result:
depfile_sources = set(result.strip().split('\n'))
return depfile_sources
def WritePackageToManifest(manifest_file, dot_packages_file, depfile_sources,
package_name, package_path):
path = urlparse.urlparse(package_path)
abs_root_path = os.path.abspath(path.path)
manifest_lib_path = os.path.join('data', 'dart-pkg', package_name, 'lib')
for root, dirs, files in os.walk(path.path):
for f in files:
# TODO(zra): What other files are needed?
if not f.endswith('.dart'):
continue
# gen_snapshot outputs all dependencies as abspaths, and some .packages
# files contain relpaths, so we must convert everything to an abspath.
full_path = os.path.abspath(os.path.join(root, f))
# Only include files that are in depfile_sources
if depfile_sources == None or full_path in depfile_sources:
relative_path = os.path.relpath(full_path, abs_root_path)
manifest_path = os.path.join(manifest_lib_path, relative_path)
manifest_file.write(manifest_path + '=' + full_path + '\n')
dot_packages_file.write(
package_name + ':file:///pkg/' + manifest_lib_path + '/\n')
def WriteManifest(args, depfile_sources):
with open(args.dot_packages) as dpfile, \
open(args.manifest_out, 'w') as mfile, \
open(args.dot_packages_out, 'w') as dpoutfile:
for line in dpfile:
package_and_uri = line.strip().split(':', 1)
WritePackageToManifest(mfile, dpoutfile, depfile_sources,
package_and_uri[0], package_and_uri[1])
mfile.write(os.path.join('data', 'dart-pkg', '.packages') + '=' +
args.dot_packages_out + '\n')
mfile.write(os.path.join('data', 'dart-pkg', 'contents') + '=' +
args.contents_out + '\n')
def main():
parser = argparse.ArgumentParser(
description="Generate a manifest from a Dart .packages file")
parser.add_argument("--contents-out",
help="Output contents file to be included in the manifest",
required=True)
parser.add_argument("--dot-packages",
help="Path to .packages file to translate",
required=True)
parser.add_argument("--dot-packages-out",
help="Output .packages file to be included in the manifest",
required=True)
parser.add_argument("--gen-snapshot",
help="Path to gen_snapshot",
required=True)
parser.add_argument("--main-dart",
help="main.dart entrypoint of the program.",
required=True)
parser.add_argument("--manifest-out",
help="Output manifest file.",
required=True)
parser.add_argument("--package",
help="The name of the package containing the lib/main.dart entrypoint",
required=True)
parser.add_argument('--url-mapping',
type=str,
action='append',
help='dart: url mappings to pass to gen_snapshot.')
args = parser.parse_args()
# Invoke gen_snapshot to get the list of .dart files used by the program.
# This is used to filter out unused files from the package.
depfile_sources = GenSnapshotDeps(args)
# TODO(zra): At some point, it will likely make sense for the flutter content
# handler to understand a metadata file describing the contents of the
# package it needs to run. For now, we'll simply write the name of the
# source package containing lib/main.dart, so that the content handler doesn't
# have to guess it from the request url.
with open(args.contents_out, 'w') as cfile:
cfile.write(args.package)
WriteManifest(args, depfile_sources)
return 0
if __name__ == '__main__':
sys.exit(main())