modparser.py 2.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105
  1. # -*- coding: utf-8 -*-
  2. #!/usr/bin/env python2
  3. from __future__ import absolute_import, print_function
  4. import modulefinder
  5. import os
  6. import pprint
  7. import sys
  8. import salt.utils.json
  9. import salt.utils.yaml
  10. try:
  11. import argparse # pylint: disable=minimum-python-version
  12. HAS_ARGPARSE = True
  13. except ImportError:
  14. HAS_ARGPARSE = False
  15. def parse():
  16. """
  17. Parse the arguments
  18. """
  19. parser = argparse.ArgumentParser()
  20. parser.add_argument(
  21. "-r",
  22. "--root",
  23. dest="root",
  24. default=".",
  25. help="The base code directory to look in",
  26. )
  27. parser.add_argument("-i", "--bif", dest="bif", default="site-packages")
  28. parser.add_argument(
  29. "-f", "--format", dest="format", choices=("pprint", "yaml"), default="pprint"
  30. )
  31. out = parser.parse_args()
  32. return out.__dict__
  33. def mod_data(opts, full):
  34. """
  35. Grab the module's data
  36. """
  37. ret = {}
  38. finder = modulefinder.ModuleFinder()
  39. try:
  40. finder.load_file(full)
  41. except ImportError as exc:
  42. print("ImportError - {0} (Reason: {1})".format(full, exc), file=sys.stderr)
  43. return ret
  44. for name, mod in finder.modules.items():
  45. basemod = name.split(".")[0]
  46. if basemod in ret:
  47. continue
  48. if basemod.startswith("_"):
  49. continue
  50. if not mod.__file__:
  51. continue
  52. if opts["bif"] not in mod.__file__:
  53. # Bif - skip
  54. continue
  55. if name == os.path.basename(mod.__file__)[:-3]:
  56. continue
  57. ret[basemod] = mod.__file__
  58. for name, err in finder.badmodules.items():
  59. basemod = name.split(".")[0]
  60. if basemod in ret:
  61. continue
  62. if basemod.startswith("_"):
  63. continue
  64. ret[basemod] = err
  65. return ret
  66. def scan(opts):
  67. """
  68. Scan the provided root for python source files
  69. """
  70. ret = {}
  71. for root, dirs, files in os.walk(opts["root"]):
  72. for fn_ in files:
  73. full = os.path.join(root, fn_)
  74. if full.endswith(".py"):
  75. ret.update(mod_data(opts, full))
  76. return ret
  77. if __name__ == "__main__":
  78. if not HAS_ARGPARSE:
  79. print("The argparse python module is required")
  80. opts = parse()
  81. try:
  82. scand = scan(opts)
  83. if opts["format"] == "yaml":
  84. print(salt.utils.yaml.safe_dump(scand))
  85. if opts["format"] == "json":
  86. print(salt.utils.json.dumps(scand))
  87. else:
  88. pprint.pprint(scand)
  89. exit(0)
  90. except KeyboardInterrupt:
  91. print("\nInterrupted on user request", file=sys.stderr)
  92. exit(1)