# HG changeset patch # User Richard Taylor # Date 1272383208 -3600 # Node ID 564986768b79fe6e1834a35f0ba3bfda1e3866cf # Parent 0c5ca7f6d8ae4050dd5c462ae2b08d160674efe3 add --query option diff -r 0c5ca7f6d8ae -r 564986768b79 sbsv2/raptor/lib/config/make.xml --- a/sbsv2/raptor/lib/config/make.xml Wed Apr 14 14:40:58 2010 +0100 +++ b/sbsv2/raptor/lib/config/make.xml Tue Apr 27 16:46:48 2010 +0100 @@ -55,7 +55,7 @@ - + @@ -63,7 +63,7 @@ - + @@ -79,7 +79,7 @@ - + @@ -87,7 +87,7 @@ - + @@ -98,6 +98,6 @@ - + diff -r 0c5ca7f6d8ae -r 564986768b79 sbsv2/raptor/python/raptor.py --- a/sbsv2/raptor/python/raptor.py Wed Apr 14 14:40:58 2010 +0100 +++ b/sbsv2/raptor/python/raptor.py Tue Apr 27 16:46:48 2010 +0100 @@ -448,9 +448,10 @@ created by the Main function. When operated by an IDE several Raptor objects may be created and operated at the same time.""" - + # mission enumeration M_BUILD = 1 - M_VERSION = 2 + M_QUERY = 2 + M_VERSION = 3 def __init__(self, home = None): @@ -520,7 +521,8 @@ self.noDependInclude = False self.noDependGenerate = False self.projects = set() - + self.queries = [] + self.cache = raptor_cache.Cache(self) self.override = {env: str(self.home)} self.targets = [] @@ -717,6 +719,11 @@ self.projects.add(projectName.lower()) return True + def AddQuery(self, q): + self.queries.append(q) + self.mission = Raptor.M_QUERY + return True + def FilterList(self, value): self.filterList = value return True @@ -1219,6 +1226,31 @@ return layers + def Query(self): + "process command-line queries." + + if self.mission != Raptor.M_QUERY: + return 0 + + # establish an object cache based on the current settings + self.LoadCache() + + # our "self" is a valid object for initialising an API Context + import raptor_api + api = raptor_api.Context(self) + + print "" % raptor_version.fullversion() + + for q in self.queries: + try: + print api.StringQuery(q) + + except Exception, e: + self.Error("exception '%s' with query '%s'", str(e), q) + + print "" + return self.errorCode + def Build(self): if self.mission != Raptor.M_BUILD: # help or version requested instead. @@ -1356,6 +1388,9 @@ # object which represents a build b = Raptor.CreateCommandlineBuild(argv) + if b.mission == Raptor.M_QUERY: + return b.Query() + return b.Build() diff -r 0c5ca7f6d8ae -r 564986768b79 sbsv2/raptor/python/raptor_api.py --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/sbsv2/raptor/python/raptor_api.py Tue Apr 27 16:46:48 2010 +0100 @@ -0,0 +1,179 @@ +# +# Copyright (c) 2010 Nokia Corporation and/or its subsidiary(-ies). +# All rights reserved. +# This component and the accompanying materials are made available +# under the terms of the License "Eclipse Public License v1.0" +# which accompanies this distribution, and is available +# at the URL "http://www.eclipse.org/legal/epl-v10.html". +# +# Initial Contributors: +# Nokia Corporation - initial contribution. +# +# Contributors: +# +# Description: +# +# raptor_api module +# +# Python API for Raptor. External code should interact with Raptor via this +# module only, as it is the only programatic interface considered public. The +# command line --query option is also implemented using this module. + +class Reply(object): + """object to return values from API calls. + """ + def __init__(self, text=""): + self.reply_text = text + + def __str__(self): + name = type(self).__name__.lower() + + str = "<" + name + end = "/>\n" + + for attribute,value in self.__dict__.items(): + if attribute != "reply_text": + str += " %s='%s'" % (attribute, value) + + if self.reply_text: + str += ">" + self.reply_text + end = "\n" % name + + str += end + + return str + +class Alias(Reply): + pass + +class Config(Reply): + pass + +class Product(Reply): + pass + +import generic_path +import raptor +import raptor_data +import re + +class Context(object): + """object to contain state information for API calls. + + For example, + + api = raptor_api.Context() + val = api.get(X) + """ + def __init__(self, initialiser=None): + # this object has a private Raptor object that can either be + # passed in or created internally. + + if initialiser == None: + self.__raptor = raptor.Raptor() + else: + self.__raptor = initialiser + + def StringQuery(self, query): + """turn a string into an API call and execute it. + + This is a convenience method for "lazy" callers. + + The return value is also converted into a string. + """ + + if query == "aliases": + aliases = self.GetAliases() + return "".join(map(str, aliases)).strip() + + elif query == "products": + variants = self.GetProducts() + return "".join(map(str, variants)).strip() + + elif query.startswith("config"): + match = re.match("config\[(.*)\]", query) + if match: + config = self.GetConfig(match.group(1)) + return str(config).strip() + else: + raise BadQuery("syntax error") + + raise BadQuery("unknown query") + + def GetAliases(self, type=""): + """extract all aliases of a given type. + + the default type is "". + to get all aliases pass type=None + """ + aliases = [] + + for a in self.__raptor.cache.aliases.values(): + if a.type == type or type == None: + r = Alias() + # copy the members we want to expose + r.name = a.name + r.meaning = a.meaning + aliases.append(r) + + return aliases + + def GetConfig(self, name): + """extract the values for a given configuration. + + 'name' should be an alias or variant followed optionally by a + dot-separated list of variants. For example "armv5_urel" or + "armv5_urel.savespace.vasco". + """ + + r = Config() + + names = name.split(".") + if names[0] in self.__raptor.cache.aliases: + x = self.__raptor.cache.FindNamedAlias(names[0]) + + if len(names) > 1: + r.fullname = x.meaning + "." + ".".join(names[1:]) + else: + r.fullname = x.meaning + + elif names[0] in self.__raptor.cache.variants: + r.fullname = name + + else: + raise BadQuery("'%s' is not an alias or a variant" % names[0]) + + tmp = raptor_data.Alias("tmp") + tmp.SetProperty("meaning", r.fullname) + + units = tmp.GenerateBuildUnits(self.__raptor.cache) + evaluator = self.__raptor.GetEvaluator(None, units[0]) + + releasepath = evaluator.Get("RELEASEPATH") + fullvariantpath = evaluator.Get("FULLVARIANTPATH") + + if releasepath and fullvariantpath: + r.outputpath = str(generic_path.Join(releasepath, fullvariantpath)) + else: + raise BadQuery("could not get outputpath for config '%s'" % name) + + return r + + def GetProducts(self): + """extract all product variants.""" + + variants = [] + + for v in self.__raptor.cache.variants.values(): + if v.type == "product": + r = Product() + # copy the members we want to expose + r.name = v.name + variants.append(r) + + return variants + +class BadQuery(Exception): + pass + +# end of the raptor_api module diff -r 0c5ca7f6d8ae -r 564986768b79 sbsv2/raptor/python/raptor_cli.py --- a/sbsv2/raptor/python/raptor_cli.py Wed Apr 14 14:40:58 2010 +0100 +++ b/sbsv2/raptor/python/raptor_cli.py Tue Apr 27 16:46:48 2010 +0100 @@ -18,13 +18,8 @@ # by a raptor.Raptor object. # -import re import types import raptor -import os -import sys -import tempfile -from raptor_utilities import getOSPlatform from optparse import OptionParser # for parsing command line parameters @@ -132,6 +127,18 @@ parser.add_option("-q","--quiet",action="store_true",dest="quiet", help="Run quietly, not generating output messages.") +parser.add_option("--query",action="append",dest="query", + help="""Access various build settings and options using a basic API. The current options are: + + * aliases - return all the values that can be sensibly used with the sbs -c option. + + * products - return all the values that can be "." appended to an alias to specialise it for a product build. + + * config[x] - return a set of values that represent the build configuration "x". Typically "x" will be an alias name or an alias followed by "." followed by a product. + + Multiple --query options can be given. + """) + parser.add_option("-s","--sysdef",action="store",dest="sys_def_file", help="System Definition XML filename.") @@ -245,8 +252,7 @@ # parse the full set of arguments (options, leftover_args) = parser.parse_args(expanded_args) - # the leftover_args are either variable assignments of the form a=b - # or target names. + # the leftover_args are target names. for leftover in leftover_args: Raptor.AddTarget(leftover) @@ -275,6 +281,7 @@ 'noDependGenerate': Raptor.SetNoDependGenerate, 'number_of_jobs': Raptor.SetJobs, 'project_name' : Raptor.AddProject, + 'query' : Raptor.AddQuery, 'filter_list' : Raptor.FilterList, 'ignore_os_detection': Raptor.IgnoreOsDetection, 'check' : Raptor.SetCheck, diff -r 0c5ca7f6d8ae -r 564986768b79 sbsv2/raptor/python/raptor_data.py --- a/sbsv2/raptor/python/raptor_data.py Wed Apr 14 14:40:58 2010 +0100 +++ b/sbsv2/raptor/python/raptor_data.py Tue Apr 27 16:46:48 2010 +0100 @@ -835,6 +835,7 @@ Model.__init__(self) Config.__init__(self) self.name = name + self.type = "" # Operations defined inside this variant. self.ops = [] @@ -855,6 +856,8 @@ self.host = value elif name == "extends": self.extends = value + elif name == "type": + self.type = value else: raise InvalidPropertyError() @@ -948,6 +951,7 @@ Config.__init__(self) self.name = name self.meaning = "" + self.type = "" self.varRefs = [] self.variants = [] @@ -962,6 +966,8 @@ for u in val.split("."): self.varRefs.append( VariantRef(ref = u) ) + elif key == "type": + self.type = val else: raise InvalidPropertyError() diff -r 0c5ca7f6d8ae -r 564986768b79 sbsv2/raptor/test/config/api.xml --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/sbsv2/raptor/test/config/api.xml Tue Apr 27 16:46:48 2010 +0100 @@ -0,0 +1,30 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff -r 0c5ca7f6d8ae -r 564986768b79 sbsv2/raptor/test/smoke_suite/query_cli.py --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/sbsv2/raptor/test/smoke_suite/query_cli.py Tue Apr 27 16:46:48 2010 +0100 @@ -0,0 +1,82 @@ +# +# Copyright (c) 2010 Nokia Corporation and/or its subsidiary(-ies). +# All rights reserved. +# This component and the accompanying materials are made available +# under the terms of the License "Eclipse Public License v1.0" +# which accompanies this distribution, and is available +# at the URL "http://www.eclipse.org/legal/epl-v10.html". +# +# Initial Contributors: +# Nokia Corporation - initial contribution. +# +# Contributors: +# +# Description: +# + +from raptor_tests import SmokeTest + +def run(): + + t = SmokeTest() + t.description = "Test the --query command-line option" + + t.name = "query_cli_alias" + t.command = "sbs --query=aliases" + t.mustmatch_singleline = [ + "", + "", + "", + "", + "", + "", + "", + "" + ] + t.mustnotmatch_singleline = [ + "", + "" + ] + t.run() + + t.name = "query_cli_product" + t.command = "sbs --query=products --configpath=test/smoke_suite/test_resources/bv" + t.mustmatch_singleline = [ + "", + "", + "", + "", + "" + ] + t.mustnotmatch_singleline = [ + "", + "" + ] + t.run() + + t.name = "query_cli_config" + t.command = "sbs --query=config[armv5_urel]" + t.mustmatch_singleline = [ + "", + "fullname='arm\.v5\.urel\.rvct.*'", + "outputpath='.*/epoc32/release/armv5/urel'", + "" + ] + t.mustnotmatch_singleline = [] + t.run() + + t.name = "query_cli_bad" + t.command = "sbs --query=nonsense" + t.mustmatch_singleline = [ + "", + "exception 'unknown query' with query 'nonsense'", + "" + ] + t.mustnotmatch_singleline = [] + t.errors = 1 + t.returncode = 1 + t.run() + + t.name = "query_cli" + t.print_result() + return t diff -r 0c5ca7f6d8ae -r 564986768b79 sbsv2/raptor/test/smoke_suite/test_resources/bv/config/variants/bv_test.xml --- a/sbsv2/raptor/test/smoke_suite/test_resources/bv/config/variants/bv_test.xml Wed Apr 14 14:40:58 2010 +0100 +++ b/sbsv2/raptor/test/smoke_suite/test_resources/bv/config/variants/bv_test.xml Tue Apr 27 16:46:48 2010 +0100 @@ -5,7 +5,7 @@ xsi:schemaLocation="http://symbian.com/xml/build build/2_0.xsd"> - + - + - +