pretty_sln.py 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171
  1. #!/usr/bin/env python
  2. # Copyright (c) 2012 Google Inc. All rights reserved.
  3. # Use of this source code is governed by a BSD-style license that can be
  4. # found in the LICENSE file.
  5. """Prints the information in a sln file in a diffable way.
  6. It first outputs each projects in alphabetical order with their
  7. dependencies.
  8. Then it outputs a possible build order.
  9. """
  10. from __future__ import print_function
  11. import os
  12. import re
  13. import sys
  14. import pretty_vcproj
  15. __author__ = 'nsylvain (Nicolas Sylvain)'
  16. def BuildProject(project, built, projects, deps):
  17. # if all dependencies are done, we can build it, otherwise we try to build the
  18. # dependency.
  19. # This is not infinite-recursion proof.
  20. for dep in deps[project]:
  21. if dep not in built:
  22. BuildProject(dep, built, projects, deps)
  23. print(project)
  24. built.append(project)
  25. def ParseSolution(solution_file):
  26. # All projects, their clsid and paths.
  27. projects = dict()
  28. # A list of dependencies associated with a project.
  29. dependencies = dict()
  30. # Regular expressions that matches the SLN format.
  31. # The first line of a project definition.
  32. begin_project = re.compile(r'^Project\("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942'
  33. r'}"\) = "(.*)", "(.*)", "(.*)"$')
  34. # The last line of a project definition.
  35. end_project = re.compile('^EndProject$')
  36. # The first line of a dependency list.
  37. begin_dep = re.compile(
  38. r'ProjectSection\(ProjectDependencies\) = postProject$')
  39. # The last line of a dependency list.
  40. end_dep = re.compile('EndProjectSection$')
  41. # A line describing a dependency.
  42. dep_line = re.compile(' *({.*}) = ({.*})$')
  43. in_deps = False
  44. solution = open(solution_file)
  45. for line in solution:
  46. results = begin_project.search(line)
  47. if results:
  48. # Hack to remove icu because the diff is too different.
  49. if results.group(1).find('icu') != -1:
  50. continue
  51. # We remove "_gyp" from the names because it helps to diff them.
  52. current_project = results.group(1).replace('_gyp', '')
  53. projects[current_project] = [results.group(2).replace('_gyp', ''),
  54. results.group(3),
  55. results.group(2)]
  56. dependencies[current_project] = []
  57. continue
  58. results = end_project.search(line)
  59. if results:
  60. current_project = None
  61. continue
  62. results = begin_dep.search(line)
  63. if results:
  64. in_deps = True
  65. continue
  66. results = end_dep.search(line)
  67. if results:
  68. in_deps = False
  69. continue
  70. results = dep_line.search(line)
  71. if results and in_deps and current_project:
  72. dependencies[current_project].append(results.group(1))
  73. continue
  74. # Change all dependencies clsid to name instead.
  75. for project in dependencies:
  76. # For each dependencies in this project
  77. new_dep_array = []
  78. for dep in dependencies[project]:
  79. # Look for the project name matching this cldis
  80. for project_info in projects:
  81. if projects[project_info][1] == dep:
  82. new_dep_array.append(project_info)
  83. dependencies[project] = sorted(new_dep_array)
  84. return (projects, dependencies)
  85. def PrintDependencies(projects, deps):
  86. print("---------------------------------------")
  87. print("Dependencies for all projects")
  88. print("---------------------------------------")
  89. print("-- --")
  90. for (project, dep_list) in sorted(deps.items()):
  91. print("Project : %s" % project)
  92. print("Path : %s" % projects[project][0])
  93. if dep_list:
  94. for dep in dep_list:
  95. print(" - %s" % dep)
  96. print("")
  97. print("-- --")
  98. def PrintBuildOrder(projects, deps):
  99. print("---------------------------------------")
  100. print("Build order ")
  101. print("---------------------------------------")
  102. print("-- --")
  103. built = []
  104. for (project, _) in sorted(deps.items()):
  105. if project not in built:
  106. BuildProject(project, built, projects, deps)
  107. print("-- --")
  108. def PrintVCProj(projects):
  109. for project in projects:
  110. print("-------------------------------------")
  111. print("-------------------------------------")
  112. print(project)
  113. print(project)
  114. print(project)
  115. print("-------------------------------------")
  116. print("-------------------------------------")
  117. project_path = os.path.abspath(os.path.join(os.path.dirname(sys.argv[1]),
  118. projects[project][2]))
  119. pretty = pretty_vcproj
  120. argv = [ '',
  121. project_path,
  122. '$(SolutionDir)=%s\\' % os.path.dirname(sys.argv[1]),
  123. ]
  124. argv.extend(sys.argv[3:])
  125. pretty.main(argv)
  126. def main():
  127. # check if we have exactly 1 parameter.
  128. if len(sys.argv) < 2:
  129. print('Usage: %s "c:\\path\\to\\project.sln"' % sys.argv[0])
  130. return 1
  131. (projects, deps) = ParseSolution(sys.argv[1])
  132. PrintDependencies(projects, deps)
  133. PrintBuildOrder(projects, deps)
  134. if '--recursive' in sys.argv:
  135. PrintVCProj(projects)
  136. return 0
  137. if __name__ == '__main__':
  138. sys.exit(main())