main.py 7.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233
  1. # Copyright (c) 2008-2010, 2012-2014 LOGILAB S.A. (Paris, FRANCE) <contact@logilab.fr>
  2. # Copyright (c) 2014 Brett Cannon <brett@python.org>
  3. # Copyright (c) 2014 Arun Persaud <arun@nubati.net>
  4. # Copyright (c) 2015-2020 Claudiu Popa <pcmanticore@gmail.com>
  5. # Copyright (c) 2015 Ionel Cristian Maries <contact@ionelmc.ro>
  6. # Copyright (c) 2016 Alexander Pervakov <frost.nzcr4@jagmort.com>
  7. # Copyright (c) 2018 ssolanki <sushobhitsolanki@gmail.com>
  8. # Copyright (c) 2019, 2021 Pierre Sassoulas <pierre.sassoulas@gmail.com>
  9. # Copyright (c) 2019 Hugo van Kemenade <hugovk@users.noreply.github.com>
  10. # Copyright (c) 2020 Peter Kolbus <peter.kolbus@gmail.com>
  11. # Copyright (c) 2020 hippo91 <guillaume.peillex@gmail.com>
  12. # Copyright (c) 2021 Antonio Quarta <sgheppy88@gmail.com>
  13. # Copyright (c) 2021 Tushar Sadhwani <tushar.sadhwani000@gmail.com>
  14. # Copyright (c) 2021 Mark Byrne <31762852+mbyrnepr2@users.noreply.github.com>
  15. # Copyright (c) 2021 bot <bot@noreply.github.com>
  16. # Copyright (c) 2021 Daniël van Noord <13665637+DanielNoord@users.noreply.github.com>
  17. # Copyright (c) 2021 Andreas Finkler <andi.finkler@gmail.com>
  18. # Copyright (c) 2021 Marc Mueller <30130371+cdce8p@users.noreply.github.com>
  19. # Licensed under the GPL: https://www.gnu.org/licenses/old-licenses/gpl-2.0.html
  20. # For details: https://github.com/PyCQA/pylint/blob/main/LICENSE
  21. """
  22. %prog [options] <packages>
  23. create UML diagrams for classes and modules in <packages>
  24. """
  25. import sys
  26. from typing import Iterable
  27. from pylint.config import ConfigurationMixIn
  28. from pylint.lint.utils import fix_import_path
  29. from pylint.pyreverse import writer
  30. from pylint.pyreverse.diadefslib import DiadefsHandler
  31. from pylint.pyreverse.inspector import Linker, project_from_files
  32. from pylint.pyreverse.utils import check_graphviz_availability, insert_default_options
  33. OPTIONS = (
  34. (
  35. "filter-mode",
  36. dict(
  37. short="f",
  38. default="PUB_ONLY",
  39. dest="mode",
  40. type="string",
  41. action="store",
  42. metavar="<mode>",
  43. help="""filter attributes and functions according to
  44. <mode>. Correct modes are :
  45. 'PUB_ONLY' filter all non public attributes
  46. [DEFAULT], equivalent to PRIVATE+SPECIAL_A
  47. 'ALL' no filter
  48. 'SPECIAL' filter Python special functions
  49. except constructor
  50. 'OTHER' filter protected and private
  51. attributes""",
  52. ),
  53. ),
  54. (
  55. "class",
  56. dict(
  57. short="c",
  58. action="append",
  59. metavar="<class>",
  60. dest="classes",
  61. default=[],
  62. help="create a class diagram with all classes related to <class>;\
  63. this uses by default the options -ASmy",
  64. ),
  65. ),
  66. (
  67. "show-ancestors",
  68. dict(
  69. short="a",
  70. action="store",
  71. metavar="<ancestor>",
  72. type="int",
  73. help="show <ancestor> generations of ancestor classes not in <projects>",
  74. ),
  75. ),
  76. (
  77. "all-ancestors",
  78. dict(
  79. short="A",
  80. default=None,
  81. help="show all ancestors off all classes in <projects>",
  82. ),
  83. ),
  84. (
  85. "show-associated",
  86. dict(
  87. short="s",
  88. action="store",
  89. metavar="<association_level>",
  90. type="int",
  91. help="show <association_level> levels of associated classes not in <projects>",
  92. ),
  93. ),
  94. (
  95. "all-associated",
  96. dict(
  97. short="S",
  98. default=None,
  99. help="show recursively all associated off all associated classes",
  100. ),
  101. ),
  102. (
  103. "show-builtin",
  104. dict(
  105. short="b",
  106. action="store_true",
  107. default=False,
  108. help="include builtin objects in representation of classes",
  109. ),
  110. ),
  111. (
  112. "module-names",
  113. dict(
  114. short="m",
  115. default=None,
  116. type="yn",
  117. metavar="<y or n>",
  118. help="include module name in representation of classes",
  119. ),
  120. ),
  121. (
  122. "only-classnames",
  123. dict(
  124. short="k",
  125. action="store_true",
  126. default=False,
  127. help="don't show attributes and methods in the class boxes; this disables -f values",
  128. ),
  129. ),
  130. (
  131. "output",
  132. dict(
  133. short="o",
  134. dest="output_format",
  135. action="store",
  136. default="dot",
  137. metavar="<format>",
  138. help="create a *.<format> output file if format available.",
  139. ),
  140. ),
  141. (
  142. "colorized",
  143. dict(
  144. dest="colorized",
  145. action="store_true",
  146. default=False,
  147. help="Use colored output. Classes/modules of the same package get the same color.",
  148. ),
  149. ),
  150. (
  151. "max-color-depth",
  152. dict(
  153. dest="max_color_depth",
  154. action="store",
  155. default=2,
  156. metavar="<depth>",
  157. type="int",
  158. help="Use separate colors up to package depth of <depth>",
  159. ),
  160. ),
  161. (
  162. "ignore",
  163. dict(
  164. type="csv",
  165. metavar="<file[,file...]>",
  166. dest="ignore_list",
  167. default=("CVS",),
  168. help="Files or directories to be skipped. They should be base names, not paths.",
  169. ),
  170. ),
  171. (
  172. "project",
  173. dict(
  174. default="",
  175. type="string",
  176. short="p",
  177. metavar="<project name>",
  178. help="set the project name.",
  179. ),
  180. ),
  181. (
  182. "output-directory",
  183. dict(
  184. default="",
  185. type="string",
  186. short="d",
  187. action="store",
  188. metavar="<output_directory>",
  189. help="set the output directory path.",
  190. ),
  191. ),
  192. )
  193. class Run(ConfigurationMixIn):
  194. """base class providing common behaviour for pyreverse commands"""
  195. options = OPTIONS
  196. def __init__(self, args: Iterable[str]):
  197. super().__init__(usage=__doc__)
  198. insert_default_options()
  199. args = self.load_command_line_configuration(args)
  200. if self.config.output_format not in ("dot", "vcg", "puml", "plantuml"):
  201. check_graphviz_availability()
  202. sys.exit(self.run(args))
  203. def run(self, args):
  204. """checking arguments and run project"""
  205. if not args:
  206. print(self.help())
  207. return 1
  208. with fix_import_path(args):
  209. project = project_from_files(
  210. args,
  211. project_name=self.config.project,
  212. black_list=self.config.ignore_list,
  213. )
  214. linker = Linker(project, tag=True)
  215. handler = DiadefsHandler(self.config)
  216. diadefs = handler.get_diadefs(project, linker)
  217. writer.DiagramWriter(self.config).write(diadefs)
  218. return 0
  219. if __name__ == "__main__":
  220. Run(sys.argv[1:])