| 
									
										
										
										
											2012-04-10 06:19:49 +08:00
										 |  |  | # 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 | 
					
						
							| 
									
										
										
										
											2012-04-11 10:58:07 +08:00
										 |  |  | anvil deploy --output=/some/bin/ :release_all | 
					
						
							| 
									
										
										
										
											2012-04-10 06:19:49 +08:00
										 |  |  | # Clean (aka delete) /some/bin/ before doing the copy | 
					
						
							| 
									
										
										
										
											2012-04-11 10:58:07 +08:00
										 |  |  | anvil deploy --clean --output=/some/bin/ :release_all | 
					
						
							| 
									
										
										
										
											2012-04-10 06:19:49 +08:00
										 |  |  | """
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | __author__ = 'benvanik@google.com (Ben Vanik)' | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | import os | 
					
						
							|  |  |  | import shutil | 
					
						
							|  |  |  | import sys | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | import anvil.commands.util as commandutil | 
					
						
							| 
									
										
										
										
											2012-04-12 05:11:34 +08:00
										 |  |  | 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__) | 
					
						
							| 
									
										
										
										
											2012-04-12 06:57:23 +08:00
										 |  |  |     self._add_common_build_hints() | 
					
						
							|  |  |  |     self.completion_hints.extend([ | 
					
						
							|  |  |  |         '-o', '--output', | 
					
						
							|  |  |  |         '-c', '--clean', | 
					
						
							|  |  |  |         ]) | 
					
						
							| 
									
										
										
										
											2012-04-12 05:11:34 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  |   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) | 
					
						
							| 
									
										
										
										
											2012-04-12 05:11:34 +08:00
										 |  |  |     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 | 
					
						
							| 
									
										
										
										
											2012-04-12 05:11:34 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  |     # Ensure output exists | 
					
						
							| 
									
										
										
										
											2012-05-01 16:02:57 +08:00
										 |  |  |     if not os.path.isdir(args.output): | 
					
						
							|  |  |  |       os.makedirs(args.output) | 
					
						
							| 
									
										
										
										
											2012-04-12 05:11:34 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  |     # 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:])) | 
					
						
							| 
									
										
										
										
											2012-04-12 05:11:34 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  |       # Make output path | 
					
						
							| 
									
										
										
										
											2012-05-01 16:02:57 +08:00
										 |  |  |       deploy_path = os.path.normpath(os.path.join(args.output, rel_path)) | 
					
						
							| 
									
										
										
										
											2012-04-12 05:11:34 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  |       # 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) | 
					
						
							| 
									
										
										
										
											2012-05-18 11:58:53 +08:00
										 |  |  |       shutil.copy(target_output, deploy_path) | 
					
						
							| 
									
										
										
										
											2012-04-12 05:11:34 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  |     return 0 if result else 1 |