1a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)# Copyright 2013 The Chromium Authors. All rights reserved. 2a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)# Use of this source code is governed by a BSD-style license that can be 3a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)# found in the LICENSE file. 4a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 5a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)"""A module for the init command.""" 6a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 7a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)import os 8a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 9a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)import cr 10a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 11a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)# The set of variables to store in the per output configuration. 12a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)OUT_CONFIG_VARS = [ 13a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 'CR_VERSION', 14a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) cr.Platform.SELECTOR, cr.BuildType.SELECTOR, cr.Arch.SELECTOR, 15a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 'CR_OUT_BASE', 'CR_OUT_FULL', 16a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)] 17a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 18a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 19a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)class InitCommand(cr.Command): 20a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) """The implementation of the init command. 21a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 22a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) The init command builds or updates an output directory. 23a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) It then uses the Prepare and Select commands to get that directory 24a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) ready to use. 25a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) """ 26a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 27a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) def __init__(self): 28a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) super(InitCommand, self).__init__() 29a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) self.requires_build_dir = False 30a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) self.help = 'Create and configure an output directory' 31a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) self.description = (""" 32a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) If the .cr directory is not present, build it and add 33a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) the specified configuration. 34a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) If the file already exists, update the configuration with any 35a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) additional settings. 36a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) """) 37a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) self._settings = [] 38a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 39a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) def AddArguments(self, subparsers): 40a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) """Overridden from cr.Command.""" 41a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) parser = super(InitCommand, self).AddArguments(subparsers) 42a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) cr.Platform.AddArguments(parser) 43a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) cr.BuildType.AddArguments(parser) 44a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) cr.Arch.AddArguments(parser) 45a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) cr.SelectCommand.AddPrepareArguments(parser) 46a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) parser.add_argument( 47a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) '-s', '--set', dest='_settings', metavar='settings', 48a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) action='append', 49a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) help='Configuration overrides.' 50a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) ) 51a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) return parser 52a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 53effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch def EarlyArgProcessing(self): 54effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch base_settings = getattr(cr.context.args, '_settings', None) 55a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) if base_settings: 56a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) self._settings.extend(base_settings) 57a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) # Do not call super early processing, we do not want to apply 58a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) # the output arg... 59effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch out = cr.base.client.GetOutArgument() 60a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) if out: 61a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) # Output directory is fully specified 62a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) # We need to deduce other settings from it's name 63a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) base, buildtype = os.path.split(out) 64a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) if not (base and buildtype): 65a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) print 'Specified output directory must be two levels' 66a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) exit(1) 67a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) if not cr.BuildType.FindPlugin(buildtype): 68a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) print 'Specified build type', buildtype, 'is not valid' 69a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) print 'Must be one of', ','.join(p.name for p in cr.BuildType.Plugins()) 70a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) exit(1) 71effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch if (cr.context.args.CR_BUILDTYPE and 72effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch cr.context.args.CR_BUILDTYPE != buildtype): 73a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) print 'If --type and --out are both specified, they must match' 74effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch print 'Got', cr.context.args.CR_BUILDTYPE, 'and', buildtype 75a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) exit(1) 76effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch platform = cr.context.args.CR_PLATFORM 77a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) if not platform: 78a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) # Try to guess platform based on output name 79a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) platforms = [p.name for p in cr.Platform.AllPlugins()] 80a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) matches = [p for p in platforms if p in base] 81a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) if len(matches) != 1: 82a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) print 'Platform is not set, and could not be guessed from', base 83a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) print 'Should be one of', ','.join(platforms) 84a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) if len(matches) > 1: 85a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) print 'Matched all of', ','.join(matches) 86a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) exit(1) 87a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) platform = matches[0] 88effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch cr.context.derived.Set( 89a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) CR_OUT_FULL=out, 90a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) CR_OUT_BASE=base, 91a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) CR_PLATFORM=platform, 92a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) CR_BUILDTYPE=buildtype, 93a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) ) 94effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch if not 'CR_OUT_BASE' in cr.context: 95effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch cr.context.derived['CR_OUT_BASE'] = 'out_{CR_PLATFORM}' 96effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch if not 'CR_OUT_FULL' in cr.context: 97effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch cr.context.derived['CR_OUT_FULL'] = os.path.join( 98a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) '{CR_OUT_BASE}', '{CR_BUILDTYPE}') 99a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 100effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch def Run(self): 101a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) """Overridden from cr.Command.""" 102effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch src_path = cr.context.Get('CR_SRC') 103a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) if not os.path.isdir(src_path): 104effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch print cr.context.Substitute('Path {CR_SRC} is not a valid client') 105a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) exit(1) 106a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 107a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) # Ensure we have an output directory override ready to fill in 108a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) # This will only be missing if we are creating a brand new output 109a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) # directory 110a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) build_package = cr.auto.build 111a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 112a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) # Collect the old version (and float convert) 113effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch old_version = cr.context.Find('CR_VERSION') 114a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) try: 115a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) old_version = float(old_version) 116a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) except (ValueError, TypeError): 117a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) old_version = 0.0 118a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) is_new = not hasattr(build_package, 'config') 119a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) if is_new: 120a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 121a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) class FakeModule(object): 122a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) OVERRIDES = cr.Config('OVERRIDES') 123a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 124a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) def __init__(self): 125a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) self.__name__ = 'config' 126a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 127a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) old_version = None 128a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) config = FakeModule() 129a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) setattr(build_package, 'config', config) 130a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) cr.plugin.ChainModuleConfigs(config) 131a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 132a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) # Force override the version 133a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) build_package.config.OVERRIDES.Set(CR_VERSION=cr.base.client.VERSION) 134a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) # Add all the variables that we always want to have 135a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) for name in OUT_CONFIG_VARS: 136effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch value = cr.context.Find(name) 137a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) build_package.config.OVERRIDES[name] = value 138a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) # Apply the settings from the command line 139a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) for setting in self._settings: 140a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) name, separator, value = setting.partition('=') 141a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) name = name.strip() 142a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) if not separator: 143a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) value = True 144a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) else: 145a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) value = cr.Config.ParseValue(value.strip()) 146a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) build_package.config.OVERRIDES[name] = value 147a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 148a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) # Run all the output directory init hooks 149010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) for hook in cr.InitHook.Plugins(): 150effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch hook.Run(old_version, build_package.config) 151a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) # Redo activations, they might have changed 152effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch cr.plugin.Activate() 153a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 154a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) # Write out the new configuration, and select it as the default 155effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch cr.base.client.WriteConfig(cr.context.Get('CR_BUILD_DIR'), 156a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) build_package.config.OVERRIDES.exported) 157a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) # Prepare the platform in here, using the updated config 158effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch cr.Platform.Prepare() 159effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch cr.SelectCommand.Select() 160