pretty_sln.py 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181
  1. #!/usr/bin/env python3
  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. import os
  11. import re
  12. import sys
  13. import pretty_vcproj
  14. __author__ = "nsylvain (Nicolas Sylvain)"
  15. def BuildProject(project, built, projects, deps):
  16. # if all dependencies are done, we can build it, otherwise we try to build the
  17. # dependency.
  18. # This is not infinite-recursion proof.
  19. for dep in deps[project]:
  20. if dep not in built:
  21. BuildProject(dep, built, projects, deps)
  22. print(project)
  23. built.append(project)
  24. def ParseSolution(solution_file):
  25. # All projects, their clsid and paths.
  26. projects = dict()
  27. # A list of dependencies associated with a project.
  28. dependencies = dict()
  29. # Regular expressions that matches the SLN format.
  30. # The first line of a project definition.
  31. begin_project = re.compile(
  32. r'^Project\("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942'
  33. r'}"\) = "(.*)", "(.*)", "(.*)"$'
  34. )
  35. # The last line of a project definition.
  36. end_project = re.compile("^EndProject$")
  37. # The first line of a dependency list.
  38. begin_dep = re.compile(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] = [
  54. results.group(2).replace("_gyp", ""),
  55. results.group(3),
  56. results.group(2),
  57. ]
  58. dependencies[current_project] = []
  59. continue
  60. results = end_project.search(line)
  61. if results:
  62. current_project = None
  63. continue
  64. results = begin_dep.search(line)
  65. if results:
  66. in_deps = True
  67. continue
  68. results = end_dep.search(line)
  69. if results:
  70. in_deps = False
  71. continue
  72. results = dep_line.search(line)
  73. if results and in_deps and current_project:
  74. dependencies[current_project].append(results.group(1))
  75. continue
  76. # Change all dependencies clsid to name instead.
  77. for project in dependencies:
  78. # For each dependencies in this project
  79. new_dep_array = []
  80. for dep in dependencies[project]:
  81. # Look for the project name matching this cldis
  82. for project_info in projects:
  83. if projects[project_info][1] == dep:
  84. new_dep_array.append(project_info)
  85. dependencies[project] = sorted(new_dep_array)
  86. return (projects, dependencies)
  87. def PrintDependencies(projects, deps):
  88. print("---------------------------------------")
  89. print("Dependencies for all projects")
  90. print("---------------------------------------")
  91. print("-- --")
  92. for (project, dep_list) in sorted(deps.items()):
  93. print("Project : %s" % project)
  94. print("Path : %s" % projects[project][0])
  95. if dep_list:
  96. for dep in dep_list:
  97. print(" - %s" % dep)
  98. print("")
  99. print("-- --")
  100. def PrintBuildOrder(projects, deps):
  101. print("---------------------------------------")
  102. print("Build order ")
  103. print("---------------------------------------")
  104. print("-- --")
  105. built = []
  106. for (project, _) in sorted(deps.items()):
  107. if project not in built:
  108. BuildProject(project, built, projects, deps)
  109. print("-- --")
  110. def PrintVCProj(projects):
  111. for project in projects:
  112. print("-------------------------------------")
  113. print("-------------------------------------")
  114. print(project)
  115. print(project)
  116. print(project)
  117. print("-------------------------------------")
  118. print("-------------------------------------")
  119. project_path = os.path.abspath(
  120. os.path.join(os.path.dirname(sys.argv[1]), projects[project][2])
  121. )
  122. pretty = pretty_vcproj
  123. argv = [
  124. "",
  125. project_path,
  126. "$(SolutionDir)=%s\\" % os.path.dirname(sys.argv[1]),
  127. ]
  128. argv.extend(sys.argv[3:])
  129. pretty.main(argv)
  130. def main():
  131. # check if we have exactly 1 parameter.
  132. if len(sys.argv) < 2:
  133. print('Usage: %s "c:\\path\\to\\project.sln"' % sys.argv[0])
  134. return 1
  135. (projects, deps) = ParseSolution(sys.argv[1])
  136. PrintDependencies(projects, deps)
  137. PrintBuildOrder(projects, deps)
  138. if "--recursive" in sys.argv:
  139. PrintVCProj(projects)
  140. return 0
  141. if __name__ == "__main__":
  142. sys.exit(main())