| #!/usr/bin/env python |
| # Copyright (c) 2015, the Dart project authors. Please see the AUTHORS file |
| # for details. All rights reserved. Use of this source code is governed by a |
| # BSD-style license that can be found in the LICENSE file. |
| """Helper for building and deploying Observatory""" |
| |
| import argparse |
| import os |
| import platform |
| import shutil |
| import subprocess |
| import sys |
| import utils |
| |
| SCRIPT_DIR = os.path.dirname(sys.argv[0]) |
| DART_ROOT = os.path.realpath(os.path.join(SCRIPT_DIR, '..')) |
| PUB_PATH = os.path.join(DART_ROOT, 'third_party', 'pkg', |
| 'pub', 'bin', 'pub.dart') |
| IGNORE_PATTERNS = shutil.ignore_patterns( |
| '*.map', |
| '*.concat.js', |
| '*.scriptUrls', |
| '*.precompiled.js', |
| 'main.*', |
| 'unittest*', |
| '*_buildLogs*', |
| '*.log', |
| '*~') |
| |
| usage = """observatory_tool.py [options]""" |
| |
| def CreateTimestampFile(options): |
| if options.stamp != '': |
| dir_name = os.path.dirname(options.stamp) |
| if dir_name != '': |
| if not os.path.exists(dir_name): |
| os.mkdir(dir_name) |
| open(options.stamp, 'w').close() |
| |
| def BuildArguments(): |
| result = argparse.ArgumentParser(usage=usage) |
| result.add_argument("--package-root", help="package root", default=None) |
| result.add_argument("--dart-executable", help="dart executable", default=None) |
| result.add_argument("--pub-executable", help="pub executable", default=None) |
| result.add_argument("--directory", help="observatory root", default=None) |
| result.add_argument("--command", help="[get, build, deploy]", default=None) |
| result.add_argument("--silent", help="silence all output", default=None) |
| result.add_argument("--sdk", help="Use prebuilt sdk", default=None) |
| result.add_argument("--stamp", help="Write a stamp file", default='') |
| return result |
| |
| def ProcessOptions(options, args): |
| # Fix broken boolean parsing in argparse, where False ends up being True. |
| if (options.silent is not None) and (options.silent == "True"): |
| options.silent = True |
| elif (options.silent is None) or (options.silent == "False"): |
| options.silent = False |
| else: |
| print "--silent expects 'True' or 'False' argument." |
| return False |
| |
| if (options.sdk is not None) and (options.sdk == "True"): |
| options.sdk = True |
| elif (options.sdk is None) or (options.sdk == "False"): |
| options.sdk = False |
| else: |
| print "--sdk expects 'True' or 'False' argument." |
| return False |
| |
| with open(os.devnull, 'wb') as silent_sink: |
| # Required options. |
| if options.command is None or options.directory is None: |
| return False |
| |
| # Set a default value for pub_snapshot. |
| options.pub_snapshot = None |
| |
| # If we have a working pub executable, try and use that. |
| # TODO(whesse): Drop the pub-executable option if it isn't used. |
| if options.pub_executable is not None: |
| try: |
| if 0 == subprocess.call([options.pub_executable, '--version'], |
| stdout=silent_sink, |
| stderr=silent_sink): |
| return True |
| except OSError as e: |
| pass |
| options.pub_executable = None |
| |
| if options.sdk and utils.CheckedInSdkCheckExecutable(): |
| # Use the checked in pub executable. |
| options.pub_snapshot = os.path.join(utils.CheckedInSdkPath(), |
| 'bin', |
| 'snapshots', |
| 'pub.dart.snapshot'); |
| try: |
| if 0 == subprocess.call([utils.CheckedInSdkExecutable(), |
| options.pub_snapshot, |
| '--version'], |
| stdout=silent_sink, |
| stderr=silent_sink): |
| return True |
| except OSError as e: |
| pass |
| options.pub_snapshot = None |
| |
| # We need a dart executable and a package root. |
| return (options.package_root is not None and |
| options.dart_executable is not None) |
| |
| def ChangeDirectory(directory): |
| os.chdir(directory); |
| |
| def DisplayBootstrapWarning(): |
| print """\ |
| |
| |
| WARNING: Your system cannot run the checked-in Dart SDK. Using the |
| bootstrap Dart executable will make debug builds slow. |
| Please see the Wiki for instructions on replacing the checked-in Dart SDK. |
| |
| https://github.com/dart-lang/sdk/wiki/The-checked-in-SDK-in-tools |
| |
| To use the dart_bootstrap binary please update the PubCommand function |
| in the tools/observatory_tool.py script. |
| |
| """ |
| |
| def PubCommand(dart_executable, |
| pub_executable, |
| pub_snapshot, |
| pkg_root, |
| command, |
| silent): |
| with open(os.devnull, 'wb') as silent_sink: |
| if pub_executable is not None: |
| executable = [pub_executable] |
| elif pub_snapshot is not None: |
| executable = [utils.CheckedInSdkExecutable(), pub_snapshot] |
| else: |
| DisplayBootstrapWarning() |
| executable = [dart_executable, '--package-root=' + pkg_root, PUB_PATH] |
| # Prevent the bootstrap Dart executable from running in regular |
| # development flow. |
| # REMOVE THE FOLLOWING LINE TO USE the dart_bootstrap binary. |
| # return False |
| if not silent: |
| print >> sys.stderr, ('Running command "%s"') % (executable + command) |
| return subprocess.call(executable + command, |
| stdout=silent_sink if silent else None, |
| stderr=silent_sink if silent else None) |
| |
| def Deploy(input_dir, output_dir): |
| shutil.rmtree(output_dir) |
| shutil.copytree(input_dir, output_dir, ignore=IGNORE_PATTERNS) |
| index_file = os.path.join(output_dir, 'web', 'index.html') |
| os.utime(index_file, None) |
| return 0 |
| |
| def RewritePubSpec(input_path, output_path, search, replace): |
| with open(input_path, 'rb') as input_file: |
| input_data = input_file.read() |
| input_data = input_data.replace(search, replace) |
| with open(output_path, 'wb+') as output_file: |
| output_file.write(input_data) |
| |
| def ExecuteCommand(options, args): |
| cmd = options.command |
| if (cmd == 'get'): |
| # Always remove pubspec.lock before running 'pub get'. |
| try: |
| os.remove('pubspec.lock'); |
| except OSError as e: |
| pass |
| return PubCommand(options.dart_executable, |
| options.pub_executable, |
| options.pub_snapshot, |
| options.package_root, |
| ['get', '--offline'], |
| options.silent) |
| elif (cmd == 'build'): |
| return PubCommand(options.dart_executable, |
| options.pub_executable, |
| options.pub_snapshot, |
| options.package_root, |
| ['build', |
| '-DOBS_VER=' + utils.GetVersion(), |
| '--output', args[0]], |
| options.silent) |
| elif (cmd == 'deploy'): |
| Deploy('build', 'deployed') |
| elif (cmd == 'rewrite'): |
| RewritePubSpec(args[0], args[1], args[2], args[3]) |
| else: |
| print >> sys.stderr, ('ERROR: command "%s" not supported') % (cmd) |
| return -1; |
| |
| def main(): |
| # Parse the options. |
| parser = BuildArguments() |
| (options, args) = parser.parse_known_args() |
| if not ProcessOptions(options, args): |
| parser.print_help() |
| return 1 |
| # Calculate absolute paths before changing directory. |
| if (options.package_root != None): |
| options.package_root = os.path.abspath(options.package_root) |
| if (options.dart_executable != None): |
| options.dart_executable = os.path.abspath(options.dart_executable) |
| if (options.pub_executable != None): |
| options.pub_executable = os.path.abspath(options.pub_executable) |
| if (options.pub_snapshot != None): |
| options.pub_snapshot = os.path.abspath(options.pub_snapshot) |
| if (options.stamp != ''): |
| options.stamp = os.path.abspath(options.stamp) |
| if len(args) == 1: |
| args[0] = os.path.abspath(args[0]) |
| # Pub must be run from the project's root directory. |
| ChangeDirectory(options.directory) |
| result = ExecuteCommand(options, args) |
| if result == 0: |
| CreateTimestampFile(options) |
| return result |
| |
| |
| if __name__ == '__main__': |
| sys.exit(main()); |