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