xref: /OK3568_Linux_fs/yocto/poky/scripts/lib/devtool/search.py (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1*4882a593Smuzhiyun# Development tool - search command plugin
2*4882a593Smuzhiyun#
3*4882a593Smuzhiyun# Copyright (C) 2015 Intel Corporation
4*4882a593Smuzhiyun#
5*4882a593Smuzhiyun# SPDX-License-Identifier: GPL-2.0-only
6*4882a593Smuzhiyun#
7*4882a593Smuzhiyun
8*4882a593Smuzhiyun"""Devtool search plugin"""
9*4882a593Smuzhiyun
10*4882a593Smuzhiyunimport os
11*4882a593Smuzhiyunimport bb
12*4882a593Smuzhiyunimport logging
13*4882a593Smuzhiyunimport argparse
14*4882a593Smuzhiyunimport re
15*4882a593Smuzhiyunfrom devtool import setup_tinfoil, parse_recipe, DevtoolError
16*4882a593Smuzhiyun
17*4882a593Smuzhiyunlogger = logging.getLogger('devtool')
18*4882a593Smuzhiyun
19*4882a593Smuzhiyundef search(args, config, basepath, workspace):
20*4882a593Smuzhiyun    """Entry point for the devtool 'search' subcommand"""
21*4882a593Smuzhiyun
22*4882a593Smuzhiyun    tinfoil = setup_tinfoil(config_only=False, basepath=basepath)
23*4882a593Smuzhiyun    try:
24*4882a593Smuzhiyun        pkgdata_dir = tinfoil.config_data.getVar('PKGDATA_DIR')
25*4882a593Smuzhiyun        defsummary = tinfoil.config_data.getVar('SUMMARY', False) or ''
26*4882a593Smuzhiyun
27*4882a593Smuzhiyun        keyword_rc = re.compile(args.keyword)
28*4882a593Smuzhiyun
29*4882a593Smuzhiyun        def print_match(pn):
30*4882a593Smuzhiyun            rd = parse_recipe(config, tinfoil, pn, True)
31*4882a593Smuzhiyun            if not rd:
32*4882a593Smuzhiyun                return
33*4882a593Smuzhiyun            summary = rd.getVar('SUMMARY')
34*4882a593Smuzhiyun            if summary == rd.expand(defsummary):
35*4882a593Smuzhiyun                summary = ''
36*4882a593Smuzhiyun            print("%s  %s" % (pn.ljust(20), summary))
37*4882a593Smuzhiyun
38*4882a593Smuzhiyun
39*4882a593Smuzhiyun        matches = []
40*4882a593Smuzhiyun        if os.path.exists(pkgdata_dir):
41*4882a593Smuzhiyun            for fn in os.listdir(pkgdata_dir):
42*4882a593Smuzhiyun                pfn = os.path.join(pkgdata_dir, fn)
43*4882a593Smuzhiyun                if not os.path.isfile(pfn):
44*4882a593Smuzhiyun                    continue
45*4882a593Smuzhiyun
46*4882a593Smuzhiyun                packages = []
47*4882a593Smuzhiyun                match = False
48*4882a593Smuzhiyun                if keyword_rc.search(fn):
49*4882a593Smuzhiyun                    match = True
50*4882a593Smuzhiyun
51*4882a593Smuzhiyun                if not match:
52*4882a593Smuzhiyun                    with open(pfn, 'r') as f:
53*4882a593Smuzhiyun                        for line in f:
54*4882a593Smuzhiyun                            if line.startswith('PACKAGES:'):
55*4882a593Smuzhiyun                                packages = line.split(':', 1)[1].strip().split()
56*4882a593Smuzhiyun
57*4882a593Smuzhiyun                    for pkg in packages:
58*4882a593Smuzhiyun                        if keyword_rc.search(pkg):
59*4882a593Smuzhiyun                            match = True
60*4882a593Smuzhiyun                            break
61*4882a593Smuzhiyun                        if os.path.exists(os.path.join(pkgdata_dir, 'runtime', pkg + '.packaged')):
62*4882a593Smuzhiyun                            with open(os.path.join(pkgdata_dir, 'runtime', pkg), 'r') as f:
63*4882a593Smuzhiyun                                for line in f:
64*4882a593Smuzhiyun                                    if ': ' in line:
65*4882a593Smuzhiyun                                        splitline = line.split(': ', 1)
66*4882a593Smuzhiyun                                        key = splitline[0]
67*4882a593Smuzhiyun                                        value = splitline[1].strip()
68*4882a593Smuzhiyun                                    key = key.replace(":" + pkg, "")
69*4882a593Smuzhiyun                                    if key in ['PKG', 'DESCRIPTION', 'FILES_INFO', 'FILERPROVIDES']:
70*4882a593Smuzhiyun                                        if keyword_rc.search(value):
71*4882a593Smuzhiyun                                            match = True
72*4882a593Smuzhiyun                                            break
73*4882a593Smuzhiyun                if match:
74*4882a593Smuzhiyun                    print_match(fn)
75*4882a593Smuzhiyun                    matches.append(fn)
76*4882a593Smuzhiyun        else:
77*4882a593Smuzhiyun            logger.warning('Package data is not available, results may be limited')
78*4882a593Smuzhiyun
79*4882a593Smuzhiyun        for recipe in tinfoil.all_recipes():
80*4882a593Smuzhiyun            if args.fixed_setup and 'nativesdk' in recipe.inherits():
81*4882a593Smuzhiyun                continue
82*4882a593Smuzhiyun
83*4882a593Smuzhiyun            match = False
84*4882a593Smuzhiyun            if keyword_rc.search(recipe.pn):
85*4882a593Smuzhiyun                match = True
86*4882a593Smuzhiyun            else:
87*4882a593Smuzhiyun                for prov in recipe.provides:
88*4882a593Smuzhiyun                    if keyword_rc.search(prov):
89*4882a593Smuzhiyun                        match = True
90*4882a593Smuzhiyun                        break
91*4882a593Smuzhiyun                if not match:
92*4882a593Smuzhiyun                    for rprov in recipe.rprovides:
93*4882a593Smuzhiyun                        if keyword_rc.search(rprov):
94*4882a593Smuzhiyun                            match = True
95*4882a593Smuzhiyun                            break
96*4882a593Smuzhiyun            if match and not recipe.pn in matches:
97*4882a593Smuzhiyun                print_match(recipe.pn)
98*4882a593Smuzhiyun    finally:
99*4882a593Smuzhiyun        tinfoil.shutdown()
100*4882a593Smuzhiyun
101*4882a593Smuzhiyun    return 0
102*4882a593Smuzhiyun
103*4882a593Smuzhiyundef register_commands(subparsers, context):
104*4882a593Smuzhiyun    """Register devtool subcommands from this plugin"""
105*4882a593Smuzhiyun    parser_search = subparsers.add_parser('search', help='Search available recipes',
106*4882a593Smuzhiyun                                            description='Searches for available recipes. Matches on recipe name, package name, description and installed files, and prints the recipe name and summary on match.',
107*4882a593Smuzhiyun                                            group='info')
108*4882a593Smuzhiyun    parser_search.add_argument('keyword', help='Keyword to search for (regular expression syntax allowed, use quotes to avoid shell expansion)')
109*4882a593Smuzhiyun    parser_search.set_defaults(func=search, no_workspace=True, fixed_setup=context.fixed_setup)
110