2005-01-31 Zoltan Varga <vargaz@freemail.hu>
[mono.git] / mcs / nunit20 / util / VSProject.cs
1 #region Copyright (c) 2002-2003, James W. Newkirk, Michael C. Two, Alexei A. Vorontsov, Charlie Poole, Philip A. Craig
2 /************************************************************************************
3 '
4 ' Copyright  2002-2003 James W. Newkirk, Michael C. Two, Alexei A. Vorontsov, Charlie Poole
5 ' Copyright  2000-2002 Philip A. Craig
6 '
7 ' This software is provided 'as-is', without any express or implied warranty. In no 
8 ' event will the authors be held liable for any damages arising from the use of this 
9 ' software.
10
11 ' Permission is granted to anyone to use this software for any purpose, including 
12 ' commercial applications, and to alter it and redistribute it freely, subject to the 
13 ' following restrictions:
14 '
15 ' 1. The origin of this software must not be misrepresented; you must not claim that 
16 ' you wrote the original software. If you use this software in a product, an 
17 ' acknowledgment (see the following) in the product documentation is required.
18 '
19 ' Portions Copyright  2002-2003 James W. Newkirk, Michael C. Two, Alexei A. Vorontsov, Charlie Poole
20 ' or Copyright  2000-2002 Philip A. Craig
21 '
22 ' 2. Altered source versions must be plainly marked as such, and must not be 
23 ' misrepresented as being the original software.
24 '
25 ' 3. This notice may not be removed or altered from any source distribution.
26 '
27 '***********************************************************************************/
28 #endregion
29
30 using System;
31 using System.IO;
32 using System.Xml;
33
34 namespace NUnit.Util
35 {
36         /// <summary>
37         /// This class allows loading information about
38         /// configurations and assemblies in a Visual
39         /// Studio project file and inspecting them.
40         /// Only the most common project types are
41         /// supported and an exception is thrown if
42         /// an attempt is made to load an invalid
43         /// file or one of an unknown type.
44         /// </summary>
45         public class VSProject
46         {
47                 #region Static and Instance Variables
48
49                 /// <summary>
50                 /// VS Project extentions
51                 /// </summary>
52                 private static readonly string[] validExtensions = { ".csproj", ".vbproj", ".vjsproj", ".vcproj" };
53                 
54                 /// <summary>
55                 /// VS Solution extension
56                 /// </summary>
57                 private static readonly string solutionExtension = ".sln";
58
59                 /// <summary>
60                 /// Path to the file storing this project
61                 /// </summary>
62                 private string projectPath;
63
64                 /// <summary>
65                 /// Collection of configs for the project
66                 /// </summary>
67                 private VSProjectConfigCollection configs;
68
69                 #endregion
70
71                 #region Constructor
72
73                 public VSProject( string projectPath )
74                 {
75                         this.projectPath = Path.GetFullPath( projectPath );
76                         configs = new VSProjectConfigCollection();              
77
78                         Load();
79                 }
80
81                 #endregion
82
83                 #region Properties
84
85                 /// <summary>
86                 /// The name of the project.
87                 /// </summary>
88                 public string Name
89                 {
90                         get { return Path.GetFileNameWithoutExtension( projectPath ); }
91                 }
92
93                 /// <summary>
94                 /// The path to the project
95                 /// </summary>
96                 public string ProjectPath
97                 {
98                         get { return projectPath; }
99                 }
100
101                 /// <summary>
102                 /// Our collection of configurations
103                 /// </summary>
104                 public VSProjectConfigCollection Configs
105                 {
106                         get { return configs; }
107                 }
108
109                 #endregion
110
111                 #region Static Methods
112
113                 public static bool IsProjectFile( string path )
114                 {
115                         string extension = Path.GetExtension( path );
116
117                         foreach( string validExtension in validExtensions )
118                                 if ( extension == validExtension )
119                                         return true;
120
121                         return false;
122                 }
123
124                 public static bool IsSolutionFile( string path )
125                 {
126                         return Path.GetExtension( path ) == solutionExtension;
127                 }
128
129                 #endregion
130
131                 #region Instance Methods
132
133                 public void Load()
134                 {
135                         if ( !IsProjectFile( projectPath ) )
136                                 ThrowInvalidFileType( projectPath );
137
138                         string projectDirectory = Path.GetFullPath( Path.GetDirectoryName( projectPath ) );
139
140                         try
141                         {
142                                 XmlDocument doc = new XmlDocument();
143                                 doc.Load( projectPath );
144
145                                 string extension = Path.GetExtension( projectPath );
146                                 string assemblyName;
147
148                                 switch ( extension )
149                                 {
150                                         case ".vcproj":
151                                                 foreach ( XmlNode configNode in doc.SelectNodes( "/VisualStudioProject/Configurations/Configuration" ) )
152                                                 {
153                                                         string name = configNode.Attributes["Name"].Value;
154                                                         string outputPath = configNode.Attributes["OutputDirectory"].Value;
155                                                         string outputDirectory = Path.Combine( projectDirectory, outputPath );
156                                                         XmlNode toolNode = configNode.SelectSingleNode( "Tool[@Name='VCLinkerTool']" );
157                                                         assemblyName = Path.GetFileName( toolNode.Attributes["OutputFile"].Value );
158                                                         string assemblyPath = Path.Combine( outputDirectory, assemblyName );
159
160                                                         VSProjectConfig config = new VSProjectConfig ( name );
161                                                         config.Assemblies.Add( assemblyPath );
162
163                                                         this.configs.Add( config );
164                                                 }
165                                         
166                                                 break;
167
168                                         case ".csproj":
169                                         case ".vbproj":
170                                         case ".vjsproj":
171                                                 XmlNode settingsNode = doc.SelectSingleNode( "/VisualStudioProject/*/Build/Settings" );
172                         
173                                                 assemblyName = settingsNode.Attributes["AssemblyName"].Value;
174                                                 string outputType = settingsNode.Attributes["OutputType"].Value;
175
176                                                 if ( outputType == "Exe" || outputType == "WinExe" )
177                                                         assemblyName = assemblyName + ".exe";
178                                                 else
179                                                         assemblyName = assemblyName + ".dll";
180
181                                                 XmlNodeList nodes = settingsNode.SelectNodes("Config");
182                                                 if ( nodes != null ) 
183                                                         foreach ( XmlNode configNode in nodes )
184                                                         {
185                                                                 string name = configNode.Attributes["Name"].Value;
186                                                                 string outputPath = configNode.Attributes["OutputPath"].Value;
187                                                                 string outputDirectory = Path.Combine( projectDirectory, outputPath );
188                                                                 string assemblyPath = Path.Combine( outputDirectory, assemblyName );
189                                 
190                                                                 VSProjectConfig config = new VSProjectConfig ( name );
191                                                                 config.Assemblies.Add( assemblyPath );
192
193                                                                 configs.Add( config );
194                                                         }
195
196                                                 break;
197
198                                         default:
199                                                 break;
200                                 }
201                         }
202                         catch( FileNotFoundException )
203                         {
204                                 throw;
205                         }
206                         catch( Exception e )
207                         {
208                                 ThrowInvalidFormat( projectPath, e );
209                         }
210                 }
211
212                 private void ThrowInvalidFileType( string projectPath )
213                 {
214                         throw new ArgumentException( 
215                                 string.Format( "Invalid project file type: {0}", 
216                                                                 Path.GetFileName( projectPath ) ) );
217                 }
218
219                 private void ThrowInvalidFormat( string projectPath, Exception e )
220                 {
221                         throw new ArgumentException( 
222                                 string.Format( "Invalid project file format: {0}", 
223                                                                 Path.GetFileName( projectPath ) ), e );
224                 }
225
226                 #endregion
227         }
228 }