anvil-build/anvil/commands/deploy_command.py

107 lines
3.3 KiB
Python
Raw Normal View History

# Copyright 2012 Google Inc. All Rights Reserved.
"""Runs a build and copies all output results of the specified rules to a path.
All of the output files of the specified rules will be copied to the target
output path. The directory structure will be exactly that of under the
various build-*/ folders but collapsed into one.
A typical deploy rule will bring together many result srcs, for example
converted audio files or compiled code, for a specific configuration.
One could have many such rules to target different configurations, such as
unoptimized/uncompiled vs. optimized/packed.
Examples:
# Copy all output files of :release_all to /some/bin/, merging the output
anvil deploy --output=/some/bin/ :release_all
# Clean (aka delete) /some/bin/ before doing the copy
anvil deploy --clean --output=/some/bin/ :release_all
"""
__author__ = 'benvanik@google.com (Ben Vanik)'
import os
import shutil
import sys
import anvil.commands.util as commandutil
from anvil.manage import ManageCommand
class DeployCommand(ManageCommand):
def __init__(self):
super(DeployCommand, self).__init__(
name='deploy',
help_short='Builds and copies output to a target path.',
help_long=__doc__)
self._add_common_build_hints()
self.completion_hints.extend([
'-o', '--output',
'-c', '--clean',
])
def create_argument_parser(self):
parser = super(DeployCommand, self).create_argument_parser()
# Add all common args
self._add_common_build_arguments(parser, targets=True)
# 'deploy' specific
parser.add_argument('-o', '--output',
dest='output',
required=True,
help=('Output path to place all results. Will be '
'created if it does not exist.'))
parser.add_argument('-c', '--clean',
dest='clean',
action='store_true',
help=('Whether to remove all output files before '
'deploying.'))
return parser
def execute(self, args, cwd):
# Build everything first
2012-05-01 16:02:57 +08:00
(result, all_target_outputs) = commandutil.run_build(cwd, args)
if not result:
# Failed - don't copy anything
return False
# Delete output, if desired
2012-05-01 16:02:57 +08:00
if args.clean:
2012-05-01 20:18:39 +08:00
try:
shutil.rmtree(args.output)
except:
pass
# Ensure output exists
2012-05-01 16:02:57 +08:00
if not os.path.isdir(args.output):
os.makedirs(args.output)
# Copy results
for target_output in all_target_outputs:
# Get path relative to root
# This will contain the build-out/ etc
rel_path = os.path.relpath(target_output, cwd)
# Strip the build-*/
2012-05-01 20:18:39 +08:00
# TODO(benvanik): a more reliable strip
rel_path_parts = rel_path.split(os.sep)
if rel_path_parts[0].startswith('build-'):
rel_path = os.path.join(*(rel_path_parts[1:]))
# Make output path
2012-05-01 16:02:57 +08:00
deploy_path = os.path.normpath(os.path.join(args.output, rel_path))
# Ensure directory exists
# TODO(benvanik): cache whether we have checked yet to reduce OS cost
deploy_dir = os.path.dirname(deploy_path)
if not os.path.isdir(deploy_dir):
os.makedirs(deploy_dir)
# Copy!
print '%s -> %s' % (target_output, deploy_path)
shutil.copy2(target_output, deploy_path)
return 0 if result else 1