issue_finder.py 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112
  1. import os
  2. import sys
  3. import argparse
  4. import datetime
  5. try:
  6. import glob
  7. except ImportError:
  8. print("Please install glob package")
  9. sys.exit()
  10. if sys.version_info[0] < 3:
  11. raise Exception("Must be using Python 3")
  12. parser = argparse.ArgumentParser(description='This script identifies issues with module documentation, including missing documentation, and incorrect file names. Output is in markdown format.',
  13. prefix_chars='--', )
  14. parser.add_argument('-m', '--modules', type=str, default='auxiliary/scanner', help='Choose the modules category to work with. Respect the module category names as in metasploit-framework. Only one category should be passed, e.g. "auxiliary/admin", "exploits/android/browser" or "encoders" are valid entries.')
  15. parser.add_argument('--show_all', action="store_true", default=False, help='Show the complete list of items. In default mode, modules with documentation are marked "[x]" and modules without are marked "[ ]". In issues mode, documentation files without module are marked "[ ]" and documentation files with module are marked "[x]".')
  16. parser.add_argument('--show_issues', action="store_true", default=False, help='Show the list of documentation files without modules instead of modules without documentation file.')
  17. parser.add_argument('-o', '--output', help="Writes to a file.")
  18. args = parser.parse_args()
  19. module_type = args.modules
  20. show_all = args.show_all
  21. show_issues = args.show_issues
  22. modules = []
  23. docs = []
  24. path = os.path.abspath(os.path.join(os.path.realpath(__file__),"..","..",".."))
  25. if os.path.exists(os.path.join(path, 'modules', module_type)):
  26. list_docs = glob.glob(os.path.join(path,'documentation/modules', module_type, '**/*.md'), recursive=True)
  27. list_modules = glob.glob(os.path.join(path, 'modules', module_type, '**/*.*'),recursive=True)
  28. else:
  29. print("Path doesn't exist. Maybe you have passed a wrong module category or maybe there isn't any documentation file yet.")
  30. sys.exit()
  31. for doc in list_docs:
  32. docs.append(doc.split('.')[0].replace('/documentation/','/'))
  33. for module in list_modules:
  34. # skip compiled python code, and python internal use files
  35. if module.split('.')[1] == 'pyc': continue
  36. if '/_' in module.split('.')[0]: continue
  37. modules.append(module.split('.')[0])
  38. missings = 0
  39. problems = 0
  40. count = 0
  41. root = 'metasploit-framework'
  42. url_root = 'https://github.com/rapid7/metasploit-framework/blob/master/modules/'
  43. if args.output:
  44. o = open(args.output, 'w')
  45. def print_or_write(line):
  46. if args.output:
  47. o.write("%s\n" %(line))
  48. return
  49. print(line)
  50. def make_link(line):
  51. # first we wenat to get the extension back
  52. for m in list_modules:
  53. if "%s." %(line) in m:
  54. ext = m
  55. break
  56. link = ext.split("/modules")[1]
  57. #link = ext.replace("/modules", url_root)
  58. return "[%s%s](%s%s)" %(root, line, url_root, link)
  59. print_or_write('# Documentation Issue Finder\n')
  60. print_or_write('Generated: %s\n' %(datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S')))
  61. if not (show_all):
  62. if not (show_issues):
  63. print_or_write('## Modules Without Documentation\n')
  64. for i in sorted(modules):
  65. if i not in docs:
  66. missings += 1
  67. print_or_write('+ [ ] %s' %(make_link(i.split('metasploit-framework')[1])))
  68. print_or_write('\n%s modules have no documentation.' %(missings))
  69. else:
  70. print_or_write('## Docs Without Modules\n')
  71. for i in sorted(docs):
  72. if i not in modules:
  73. problems += 1
  74. print_or_write('+ [ ] %s' %(make_link(i.split('metasploit-framework')[1])))
  75. print_or_write('\n%s doc files do not correspond to any module.' %(problems))
  76. else:
  77. count = 0
  78. if not (show_issues):
  79. print_or_write('## Modules Without Documentation\n')
  80. for i in sorted(modules):
  81. if i in docs:
  82. print_or_write('+ [x] %s' %(make_link(i.split('metasploit-framework')[1])))
  83. else:
  84. print_or_write('+ [ ] %s' %(make_link(i.split('metasploit-framework')[1])))
  85. count += 1
  86. print_or_write('\n%s modules out of %s (%d%%) have no documentation.' %(count, len(modules), float(count)/len(modules) * 100.0))
  87. else:
  88. print_or_write('## Docs Without Modules\n')
  89. for i in sorted(docs):
  90. if i in modules:
  91. print_or_write('+ [x] %s' %(make_link(i.split('metasploit-framework')[1])))
  92. else:
  93. print_or_write('+ [ ] %s' %(make_link(i.split('metasploit-framework')[1])))
  94. count += 1
  95. print_or_write('\n%s doc files out of %s do not correspond to any module.' %(count, len(docs)))
  96. if args.output:
  97. o.close()