pretty_sln.py 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182
  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(
  33. r'^Project\("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942'
  34. r'}"\) = "(.*)", "(.*)", "(.*)"$'
  35. )
  36. # The last line of a project definition.
  37. end_project = re.compile("^EndProject$")
  38. # The first line of a dependency list.
  39. begin_dep = re.compile(r"ProjectSection\(ProjectDependencies\) = postProject$")
  40. # The last line of a dependency list.
  41. end_dep = re.compile("EndProjectSection$")
  42. # A line describing a dependency.
  43. dep_line = re.compile(" *({.*}) = ({.*})$")
  44. in_deps = False
  45. solution = open(solution_file)
  46. for line in solution:
  47. results = begin_project.search(line)
  48. if results:
  49. # Hack to remove icu because the diff is too different.
  50. if results.group(1).find("icu") != -1:
  51. continue
  52. # We remove "_gyp" from the names because it helps to diff them.
  53. current_project = results.group(1).replace("_gyp", "")
  54. projects[current_project] = [
  55. results.group(2).replace("_gyp", ""),
  56. results.group(3),
  57. results.group(2),
  58. ]
  59. dependencies[current_project] = []
  60. continue
  61. results = end_project.search(line)
  62. if results:
  63. current_project = None
  64. continue
  65. results = begin_dep.search(line)
  66. if results:
  67. in_deps = True
  68. continue
  69. results = end_dep.search(line)
  70. if results:
  71. in_deps = False
  72. continue
  73. results = dep_line.search(line)
  74. if results and in_deps and current_project:
  75. dependencies[current_project].append(results.group(1))
  76. continue
  77. # Change all dependencies clsid to name instead.
  78. for project in dependencies:
  79. # For each dependencies in this project
  80. new_dep_array = []
  81. for dep in dependencies[project]:
  82. # Look for the project name matching this cldis
  83. for project_info in projects:
  84. if projects[project_info][1] == dep:
  85. new_dep_array.append(project_info)
  86. dependencies[project] = sorted(new_dep_array)
  87. return (projects, dependencies)
  88. def PrintDependencies(projects, deps):
  89. print("---------------------------------------")
  90. print("Dependencies for all projects")
  91. print("---------------------------------------")
  92. print("-- --")
  93. for (project, dep_list) in sorted(deps.items()):
  94. print("Project : %s" % project)
  95. print("Path : %s" % projects[project][0])
  96. if dep_list:
  97. for dep in dep_list:
  98. print(" - %s" % dep)
  99. print("")
  100. print("-- --")
  101. def PrintBuildOrder(projects, deps):
  102. print("---------------------------------------")
  103. print("Build order ")
  104. print("---------------------------------------")
  105. print("-- --")
  106. built = []
  107. for (project, _) in sorted(deps.items()):
  108. if project not in built:
  109. BuildProject(project, built, projects, deps)
  110. print("-- --")
  111. def PrintVCProj(projects):
  112. for project in projects:
  113. print("-------------------------------------")
  114. print("-------------------------------------")
  115. print(project)
  116. print(project)
  117. print(project)
  118. print("-------------------------------------")
  119. print("-------------------------------------")
  120. project_path = os.path.abspath(
  121. os.path.join(os.path.dirname(sys.argv[1]), projects[project][2])
  122. )
  123. pretty = pretty_vcproj
  124. argv = [
  125. "",
  126. project_path,
  127. "$(SolutionDir)=%s\\" % os.path.dirname(sys.argv[1]),
  128. ]
  129. argv.extend(sys.argv[3:])
  130. pretty.main(argv)
  131. def main():
  132. # check if we have exactly 1 parameter.
  133. if len(sys.argv) < 2:
  134. print('Usage: %s "c:\\path\\to\\project.sln"' % sys.argv[0])
  135. return 1
  136. (projects, deps) = ParseSolution(sys.argv[1])
  137. PrintDependencies(projects, deps)
  138. PrintBuildOrder(projects, deps)
  139. if "--recursive" in sys.argv:
  140. PrintVCProj(projects)
  141. return 0
  142. if __name__ == "__main__":
  143. sys.exit(main())