search.py 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118
  1. # Development tool - search command plugin
  2. #
  3. # Copyright (C) 2015 Intel Corporation
  4. #
  5. # This program is free software; you can redistribute it and/or modify
  6. # it under the terms of the GNU General Public License version 2 as
  7. # published by the Free Software Foundation.
  8. #
  9. # This program is distributed in the hope that it will be useful,
  10. # but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12. # GNU General Public License for more details.
  13. #
  14. # You should have received a copy of the GNU General Public License along
  15. # with this program; if not, write to the Free Software Foundation, Inc.,
  16. # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
  17. """Devtool search plugin"""
  18. import os
  19. import bb
  20. import logging
  21. import argparse
  22. import re
  23. from devtool import setup_tinfoil, parse_recipe, DevtoolError
  24. logger = logging.getLogger('devtool')
  25. def search(args, config, basepath, workspace):
  26. """Entry point for the devtool 'search' subcommand"""
  27. tinfoil = setup_tinfoil(config_only=False, basepath=basepath)
  28. try:
  29. pkgdata_dir = tinfoil.config_data.getVar('PKGDATA_DIR')
  30. defsummary = tinfoil.config_data.getVar('SUMMARY', False) or ''
  31. keyword_rc = re.compile(args.keyword)
  32. def print_match(pn):
  33. rd = parse_recipe(config, tinfoil, pn, True)
  34. if not rd:
  35. return
  36. summary = rd.getVar('SUMMARY')
  37. if summary == rd.expand(defsummary):
  38. summary = ''
  39. print("%s %s" % (pn.ljust(20), summary))
  40. matches = []
  41. if os.path.exists(pkgdata_dir):
  42. for fn in os.listdir(pkgdata_dir):
  43. pfn = os.path.join(pkgdata_dir, fn)
  44. if not os.path.isfile(pfn):
  45. continue
  46. packages = []
  47. match = False
  48. if keyword_rc.search(fn):
  49. match = True
  50. if not match:
  51. with open(pfn, 'r') as f:
  52. for line in f:
  53. if line.startswith('PACKAGES:'):
  54. packages = line.split(':', 1)[1].strip().split()
  55. for pkg in packages:
  56. if keyword_rc.search(pkg):
  57. match = True
  58. break
  59. if os.path.exists(os.path.join(pkgdata_dir, 'runtime', pkg + '.packaged')):
  60. with open(os.path.join(pkgdata_dir, 'runtime', pkg), 'r') as f:
  61. for line in f:
  62. if ': ' in line:
  63. splitline = line.split(':', 1)
  64. key = splitline[0]
  65. value = splitline[1].strip()
  66. if key in ['PKG_%s' % pkg, 'DESCRIPTION', 'FILES_INFO'] or key.startswith('FILERPROVIDES_'):
  67. if keyword_rc.search(value):
  68. match = True
  69. break
  70. if match:
  71. print_match(fn)
  72. matches.append(fn)
  73. else:
  74. logger.warning('Package data is not available, results may be limited')
  75. for recipe in tinfoil.all_recipes():
  76. if args.fixed_setup and 'nativesdk' in recipe.inherits():
  77. continue
  78. match = False
  79. if keyword_rc.search(recipe.pn):
  80. match = True
  81. else:
  82. for prov in recipe.provides:
  83. if keyword_rc.search(prov):
  84. match = True
  85. break
  86. if not match:
  87. for rprov in recipe.rprovides:
  88. if keyword_rc.search(rprov):
  89. match = True
  90. break
  91. if match and not recipe.pn in matches:
  92. print_match(recipe.pn)
  93. finally:
  94. tinfoil.shutdown()
  95. return 0
  96. def register_commands(subparsers, context):
  97. """Register devtool subcommands from this plugin"""
  98. parser_search = subparsers.add_parser('search', help='Search available recipes',
  99. description='Searches for available recipes. Matches on recipe name, package name, description and installed files, and prints the recipe name and summary on match.',
  100. group='info')
  101. parser_search.add_argument('keyword', help='Keyword to search for (regular expression syntax allowed, use quotes to avoid shell expansion)')
  102. parser_search.set_defaults(func=search, no_workspace=True, fixed_setup=context.fixed_setup)