aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/Prebuild/src/Core/Targets/VSGenericTarget.cs
diff options
context:
space:
mode:
Diffstat (limited to 'Prebuild/src/Core/Targets/VSGenericTarget.cs')
-rw-r--r--Prebuild/src/Core/Targets/VSGenericTarget.cs1894
1 files changed, 972 insertions, 922 deletions
diff --git a/Prebuild/src/Core/Targets/VSGenericTarget.cs b/Prebuild/src/Core/Targets/VSGenericTarget.cs
index cd3f5bb..af61704 100644
--- a/Prebuild/src/Core/Targets/VSGenericTarget.cs
+++ b/Prebuild/src/Core/Targets/VSGenericTarget.cs
@@ -1,922 +1,972 @@
1#region BSD License 1#region BSD License
2/* 2/*
3Copyright (c) 2008 Matthew Holmes (matthew@wildfiregames.com), John Anderson (sontek@gmail.com) 3Copyright (c) 2008 Matthew Holmes (matthew@wildfiregames.com), John Anderson (sontek@gmail.com)
4 4
5Redistribution and use in source and binary forms, with or without modification, are permitted 5Redistribution and use in source and binary forms, with or without modification, are permitted
6provided that the following conditions are met: 6provided that the following conditions are met:
7 7
8 * Redistributions of source code must retain the above copyright notice, this list of conditions 8 * Redistributions of source code must retain the above copyright notice, this list of conditions
9 and the following disclaimer. 9 and the following disclaimer.
10 * Redistributions in binary form must reproduce the above copyright notice, this list of conditions 10 * Redistributions in binary form must reproduce the above copyright notice, this list of conditions
11 and the following disclaimer in the documentation and/or other materials provided with the 11 and the following disclaimer in the documentation and/or other materials provided with the
12 distribution. 12 distribution.
13 * The name of the author may not be used to endorse or promote products derived from this software 13 * The name of the author may not be used to endorse or promote products derived from this software
14 without specific prior written permission. 14 without specific prior written permission.
15 15
16THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, 16THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING,
17BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 17BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 18ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
19EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 19EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
20OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY 20OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
21OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 21OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
22IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 22IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
23 */ 23 */
24#endregion 24#endregion
25 25
26using System; 26using System;
27using System.Collections.Generic; 27using System.Collections.Generic;
28using System.IO; 28using System.Collections.Specialized;
29using Prebuild.Core.Interfaces; 29using System.IO;
30using Prebuild.Core.Nodes; 30using Prebuild.Core.Interfaces;
31using Prebuild.Core.Utilities; 31using Prebuild.Core.Nodes;
32using System.CodeDom.Compiler; 32using Prebuild.Core.Utilities;
33 33using System.CodeDom.Compiler;
34namespace Prebuild.Core.Targets 34
35{ 35namespace Prebuild.Core.Targets
36 36{
37 /// <summary> 37
38 /// 38 /// <summary>
39 /// </summary> 39 ///
40 public abstract class VSGenericTarget : ITarget 40 /// </summary>
41 { 41 public abstract class VSGenericTarget : ITarget
42 #region Fields 42 {
43 43 #region Fields
44 readonly Dictionary<string, ToolInfo> tools = new Dictionary<string, ToolInfo>(); 44
45 Kernel kernel; 45 readonly Dictionary<string, ToolInfo> tools = new Dictionary<string, ToolInfo>();
46 #endregion 46// NameValueCollection CopyFiles = new NameValueCollection();
47 47 Kernel kernel;
48 #region Properties 48 #endregion
49 /// <summary> 49
50 /// Gets or sets the solution version. 50 #region Properties
51 /// </summary> 51 /// <summary>
52 /// <value>The solution version.</value> 52 /// Gets or sets the solution version.
53 public abstract string SolutionVersion { get; } 53 /// </summary>
54 /// <summary> 54 /// <value>The solution version.</value>
55 /// Gets or sets the product version. 55 public abstract string SolutionVersion { get; }
56 /// </summary> 56 /// <summary>
57 /// <value>The product version.</value> 57 /// Gets or sets the product version.
58 public abstract string ProductVersion { get; } 58 /// </summary>
59 /// <summary> 59 /// <value>The product version.</value>
60 /// Gets or sets the schema version. 60 public abstract string ProductVersion { get; }
61 /// </summary> 61 /// <summary>
62 /// <value>The schema version.</value> 62 /// Gets or sets the schema version.
63 public abstract string SchemaVersion { get; } 63 /// </summary>
64 /// <summary> 64 /// <value>The schema version.</value>
65 /// Gets or sets the name of the version. 65 public abstract string SchemaVersion { get; }
66 /// </summary> 66 /// <summary>
67 /// <value>The name of the version.</value> 67 /// Gets or sets the name of the version.
68 public abstract string VersionName { get; } 68 /// </summary>
69 /// <summary> 69 /// <value>The name of the version.</value>
70 /// Gets or sets the version. 70 public abstract string VersionName { get; }
71 /// </summary> 71 /// <summary>
72 /// <value>The version.</value> 72 /// Gets or sets the version.
73 public abstract VSVersion Version { get; } 73 /// </summary>
74 /// <summary> 74 /// <value>The version.</value>
75 /// Gets the name. 75 public abstract VSVersion Version { get; }
76 /// </summary> 76 /// <summary>
77 /// <value>The name.</value> 77 /// Gets the name.
78 public abstract string Name { get; } 78 /// </summary>
79 79 /// <value>The name.</value>
80 protected abstract string GetToolsVersionXml(FrameworkVersion version); 80 public abstract string Name { get; }
81 public abstract string SolutionTag { get; } 81
82 82 protected abstract string GetToolsVersionXml(FrameworkVersion version);
83 #endregion 83 public abstract string SolutionTag { get; }
84 84
85 #region Constructors 85 #endregion
86 86
87 /// <summary> 87 #region Constructors
88 /// Initializes a new instance of the <see cref="VSGenericTarget"/> class. 88
89 /// </summary> 89 /// <summary>
90 protected VSGenericTarget() 90 /// Initializes a new instance of the <see cref="VSGenericTarget"/> class.
91 { 91 /// </summary>
92 tools["C#"] = new ToolInfo("C#", "{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}", "csproj", "CSHARP", "$(MSBuildBinPath)\\Microsoft.CSHARP.Targets"); 92 protected VSGenericTarget()
93 tools["Database"] = new ToolInfo("Database", "{4F174C21-8C12-11D0-8340-0000F80270F8}", "dbp", "UNKNOWN"); 93 {
94 tools["Boo"] = new ToolInfo("Boo", "{45CEA7DC-C2ED-48A6-ACE0-E16144C02365}", "booproj", "Boo", "$(BooBinPath)\\Boo.Microsoft.Build.targets"); 94 tools["C#"] = new ToolInfo("C#", "{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}", "csproj", "CSHARP", "$(MSBuildBinPath)\\Microsoft.CSHARP.Targets");
95 tools["VisualBasic"] = new ToolInfo("VisualBasic", "{F184B08F-C81C-45F6-A57F-5ABD9991F28F}", "vbproj", "VisualBasic", "$(MSBuildBinPath)\\Microsoft.VisualBasic.Targets"); 95 tools["Database"] = new ToolInfo("Database", "{4F174C21-8C12-11D0-8340-0000F80270F8}", "dbp", "UNKNOWN");
96 tools["Folder"] = new ToolInfo("Folder", "{2150E333-8FDC-42A3-9474-1A3956D46DE8}", null, null); 96 tools["Boo"] = new ToolInfo("Boo", "{45CEA7DC-C2ED-48A6-ACE0-E16144C02365}", "booproj", "Boo", "$(BooBinPath)\\Boo.Microsoft.Build.targets");
97 } 97 tools["VisualBasic"] = new ToolInfo("VisualBasic", "{F184B08F-C81C-45F6-A57F-5ABD9991F28F}", "vbproj", "VisualBasic", "$(MSBuildBinPath)\\Microsoft.VisualBasic.Targets");
98 98 tools["Folder"] = new ToolInfo("Folder", "{2150E333-8FDC-42A3-9474-1A3956D46DE8}", null, null);
99 #endregion 99 }
100 100
101 #region Private Methods 101 #endregion
102 102
103 private string MakeRefPath(ProjectNode project) 103 #region Private Methods
104 { 104
105 string ret = ""; 105 private string MakeRefPath(ProjectNode project)
106 foreach (ReferencePathNode node in project.ReferencePaths) 106 {
107 { 107 string ret = "";
108 try 108 foreach (ReferencePathNode node in project.ReferencePaths)
109 { 109 {
110 string fullPath = Helper.ResolvePath(node.Path); 110 try
111 if (ret.Length < 1) 111 {
112 { 112 string fullPath = Helper.ResolvePath(node.Path);
113 ret = fullPath; 113 if (ret.Length < 1)
114 } 114 {
115 else 115 ret = fullPath;
116 { 116 }
117 ret += ";" + fullPath; 117 else
118 } 118 {
119 } 119 ret += ";" + fullPath;
120 catch (ArgumentException) 120 }
121 { 121 }
122 kernel.Log.Write(LogType.Warning, "Could not resolve reference path: {0}", node.Path); 122 catch (ArgumentException)
123 } 123 {
124 } 124 kernel.Log.Write(LogType.Warning, "Could not resolve reference path: {0}", node.Path);
125 125 }
126 return ret; 126 }
127 } 127
128 128 return ret;
129 private static ProjectNode FindProjectInSolution(string name, SolutionNode solution) 129 }
130 { 130
131 SolutionNode node = solution; 131 private static ProjectNode FindProjectInSolution(string name, SolutionNode solution)
132 132 {
133 while (node.Parent is SolutionNode) 133 SolutionNode node = solution;
134 node = node.Parent as SolutionNode; 134
135 135 while (node.Parent is SolutionNode)
136 return FindProjectInSolutionRecursively(name, node); 136 node = node.Parent as SolutionNode;
137 } 137
138 138 return FindProjectInSolutionRecursively(name, node);
139 private static ProjectNode FindProjectInSolutionRecursively(string name, SolutionNode solution) 139 }
140 { 140
141 if (solution.ProjectsTable.ContainsKey(name)) 141 private static ProjectNode FindProjectInSolutionRecursively(string name, SolutionNode solution)
142 return solution.ProjectsTable[name]; 142 {
143 143 if (solution.ProjectsTable.ContainsKey(name))
144 foreach (SolutionNode child in solution.Solutions) 144 return solution.ProjectsTable[name];
145 { 145
146 ProjectNode node = FindProjectInSolutionRecursively(name, child); 146 foreach (SolutionNode child in solution.Solutions)
147 if (node != null) 147 {
148 return node; 148 ProjectNode node = FindProjectInSolutionRecursively(name, child);
149 } 149 if (node != null)
150 150 return node;
151 return null; 151 }
152 } 152
153 153 return null;
154 private void WriteProject(SolutionNode solution, ProjectNode project) 154 }
155 { 155
156 if (!tools.ContainsKey(project.Language)) 156 private void WriteProject(SolutionNode solution, ProjectNode project)
157 { 157 {
158 throw new UnknownLanguageException("Unknown .NET language: " + project.Language); 158 if (!tools.ContainsKey(project.Language))
159 } 159 {
160 160 throw new UnknownLanguageException("Unknown .NET language: " + project.Language);
161 ToolInfo toolInfo = tools[project.Language]; 161 }
162 string projectFile = Helper.MakeFilePath(project.FullPath, project.Name, toolInfo.FileExtension); 162
163 StreamWriter ps = new StreamWriter(projectFile); 163 ToolInfo toolInfo = tools[project.Language];
164 164 string projectFile = Helper.MakeFilePath(project.FullPath, project.Name, toolInfo.FileExtension);
165 kernel.CurrentWorkingDirectory.Push(); 165 StreamWriter ps = new StreamWriter(projectFile);
166 Helper.SetCurrentDir(Path.GetDirectoryName(projectFile)); 166
167 167 kernel.CurrentWorkingDirectory.Push();
168 #region Project File 168 Helper.SetCurrentDir(Path.GetDirectoryName(projectFile));
169 using (ps) 169
170 { 170 #region Project File
171 ps.WriteLine("<Project DefaultTargets=\"Build\" xmlns=\"http://schemas.microsoft.com/developer/msbuild/2003\" {0}>", GetToolsVersionXml(project.FrameworkVersion)); 171 using (ps)
172 ps.WriteLine(" <PropertyGroup>"); 172 {
173 ps.WriteLine(" <ProjectType>Local</ProjectType>"); 173 string targets = "";
174 ps.WriteLine(" <ProductVersion>{0}</ProductVersion>", ProductVersion); 174
175 ps.WriteLine(" <SchemaVersion>{0}</SchemaVersion>", SchemaVersion); 175 if(project.Files.CopyFiles > 0)
176 ps.WriteLine(" <ProjectGuid>{{{0}}}</ProjectGuid>", project.Guid.ToString().ToUpper()); 176 targets = "Build;CopyFiles";
177 177 else
178 // Visual Studio has a hard coded guid for the project type 178 targets = "Build";
179 if (project.Type == ProjectType.Web) 179
180 ps.WriteLine(" <ProjectTypeGuids>{349c5851-65df-11da-9384-00065b846f21};{fae04ec0-301f-11d3-bf4b-00c04f79efbc}</ProjectTypeGuids>"); 180 ps.WriteLine("<Project DefaultTargets=\"{0}\" xmlns=\"http://schemas.microsoft.com/developer/msbuild/2003\" {1}>", targets, GetToolsVersionXml(project.FrameworkVersion));
181 ps.WriteLine(" <Configuration Condition=\" '$(Configuration)' == '' \">Debug</Configuration>"); 181 ps.WriteLine(" <PropertyGroup>");
182 ps.WriteLine(" <ApplicationIcon>{0}</ApplicationIcon>", project.AppIcon); 182 ps.WriteLine(" <ProjectType>Local</ProjectType>");
183 ps.WriteLine(" <AssemblyKeyContainerName>"); 183 ps.WriteLine(" <ProductVersion>{0}</ProductVersion>", ProductVersion);
184 ps.WriteLine(" </AssemblyKeyContainerName>"); 184 ps.WriteLine(" <SchemaVersion>{0}</SchemaVersion>", SchemaVersion);
185 ps.WriteLine(" <AssemblyName>{0}</AssemblyName>", project.AssemblyName); 185 ps.WriteLine(" <ProjectGuid>{{{0}}}</ProjectGuid>", project.Guid.ToString().ToUpper());
186 foreach (ConfigurationNode conf in project.Configurations) 186
187 { 187 // Visual Studio has a hard coded guid for the project type
188 if (conf.Options.KeyFile != "") 188 if (project.Type == ProjectType.Web)
189 { 189 ps.WriteLine(" <ProjectTypeGuids>{349c5851-65df-11da-9384-00065b846f21};{fae04ec0-301f-11d3-bf4b-00c04f79efbc}</ProjectTypeGuids>");
190 ps.WriteLine(" <AssemblyOriginatorKeyFile>{0}</AssemblyOriginatorKeyFile>", conf.Options.KeyFile); 190 ps.WriteLine(" <Configuration Condition=\" '$(Configuration)' == '' \">Debug</Configuration>");
191 ps.WriteLine(" <SignAssembly>true</SignAssembly>"); 191 ps.WriteLine(" <ApplicationIcon>{0}</ApplicationIcon>", project.AppIcon);
192 break; 192 ps.WriteLine(" <AssemblyKeyContainerName>");
193 } 193 ps.WriteLine(" </AssemblyKeyContainerName>");
194 } 194 ps.WriteLine(" <AssemblyName>{0}</AssemblyName>", project.AssemblyName);
195 ps.WriteLine(" <DefaultClientScript>JScript</DefaultClientScript>"); 195 foreach (ConfigurationNode conf in project.Configurations)
196 ps.WriteLine(" <DefaultHTMLPageLayout>Grid</DefaultHTMLPageLayout>"); 196 {
197 ps.WriteLine(" <DefaultTargetSchema>IE50</DefaultTargetSchema>"); 197 if (conf.Options.KeyFile != "")
198 ps.WriteLine(" <DelaySign>false</DelaySign>"); 198 {
199 ps.WriteLine(" <TargetFrameworkVersion>{0}</TargetFrameworkVersion>", project.FrameworkVersion.ToString().Replace("_", ".")); 199 ps.WriteLine(" <AssemblyOriginatorKeyFile>{0}</AssemblyOriginatorKeyFile>", conf.Options.KeyFile);
200 200 ps.WriteLine(" <SignAssembly>true</SignAssembly>");
201 ps.WriteLine(" <OutputType>{0}</OutputType>", project.Type == ProjectType.Web ? ProjectType.Library.ToString() : project.Type.ToString()); 201 break;
202 ps.WriteLine(" <AppDesignerFolder>{0}</AppDesignerFolder>", project.DesignerFolder); 202 }
203 ps.WriteLine(" <RootNamespace>{0}</RootNamespace>", project.RootNamespace); 203 }
204 ps.WriteLine(" <StartupObject>{0}</StartupObject>", project.StartupObject); 204 ps.WriteLine(" <DefaultClientScript>JScript</DefaultClientScript>");
205 if (string.IsNullOrEmpty(project.DebugStartParameters)) 205 ps.WriteLine(" <DefaultHTMLPageLayout>Grid</DefaultHTMLPageLayout>");
206 { 206 ps.WriteLine(" <DefaultTargetSchema>IE50</DefaultTargetSchema>");
207 ps.WriteLine(" <StartArguments>{0}</StartArguments>", project.DebugStartParameters); 207 ps.WriteLine(" <DelaySign>false</DelaySign>");
208 } 208 ps.WriteLine(" <TargetFrameworkVersion>{0}</TargetFrameworkVersion>", project.FrameworkVersion.ToString().Replace("_", "."));
209 ps.WriteLine(" <FileUpgradeFlags>"); 209
210 ps.WriteLine(" </FileUpgradeFlags>"); 210 ps.WriteLine(" <OutputType>{0}</OutputType>", project.Type == ProjectType.Web ? ProjectType.Library.ToString() : project.Type.ToString());
211 211 ps.WriteLine(" <AppDesignerFolder>{0}</AppDesignerFolder>", project.DesignerFolder);
212 ps.WriteLine(" </PropertyGroup>"); 212 ps.WriteLine(" <RootNamespace>{0}</RootNamespace>", project.RootNamespace);
213 213 ps.WriteLine(" <StartupObject>{0}</StartupObject>", project.StartupObject);
214 foreach (ConfigurationNode conf in project.Configurations) 214 if (string.IsNullOrEmpty(project.DebugStartParameters))
215 { 215 {
216 ps.Write(" <PropertyGroup "); 216 ps.WriteLine(" <StartArguments>{0}</StartArguments>", project.DebugStartParameters);
217 ps.WriteLine("Condition=\" '$(Configuration)|$(Platform)' == '{0}|{1}' \">", conf.Name, conf.Platform); 217 }
218 ps.WriteLine(" <AllowUnsafeBlocks>{0}</AllowUnsafeBlocks>", conf.Options["AllowUnsafe"]); 218 ps.WriteLine(" <FileUpgradeFlags>");
219 ps.WriteLine(" <BaseAddress>{0}</BaseAddress>", conf.Options["BaseAddress"]); 219 ps.WriteLine(" </FileUpgradeFlags>");
220 ps.WriteLine(" <CheckForOverflowUnderflow>{0}</CheckForOverflowUnderflow>", conf.Options["CheckUnderflowOverflow"]); 220
221 ps.WriteLine(" <ConfigurationOverrideFile>"); 221 ps.WriteLine(" </PropertyGroup>");
222 ps.WriteLine(" </ConfigurationOverrideFile>"); 222
223 ps.WriteLine(" <DefineConstants>{0}</DefineConstants>", conf.Options["CompilerDefines"]); 223 foreach (ConfigurationNode conf in project.Configurations)
224 ps.WriteLine(" <DocumentationFile>{0}</DocumentationFile>", Helper.NormalizePath(conf.Options["XmlDocFile"].ToString())); 224 {
225 ps.WriteLine(" <DebugSymbols>{0}</DebugSymbols>", conf.Options["DebugInformation"]); 225 ps.Write(" <PropertyGroup ");
226 ps.WriteLine(" <FileAlignment>{0}</FileAlignment>", conf.Options["FileAlignment"]); 226 ps.WriteLine("Condition=\" '$(Configuration)|$(Platform)' == '{0}|{1}' \">", conf.Name, conf.Platform);
227 ps.WriteLine(" <Optimize>{0}</Optimize>", conf.Options["OptimizeCode"]); 227 ps.WriteLine(" <AllowUnsafeBlocks>{0}</AllowUnsafeBlocks>", conf.Options["AllowUnsafe"]);
228 if (project.Type != ProjectType.Web) 228 ps.WriteLine(" <BaseAddress>{0}</BaseAddress>", conf.Options["BaseAddress"]);
229 ps.WriteLine(" <OutputPath>{0}</OutputPath>", 229 ps.WriteLine(" <CheckForOverflowUnderflow>{0}</CheckForOverflowUnderflow>", conf.Options["CheckUnderflowOverflow"]);
230 Helper.EndPath(Helper.NormalizePath(conf.Options["OutputPath"].ToString()))); 230 ps.WriteLine(" <ConfigurationOverrideFile>");
231 else 231 ps.WriteLine(" </ConfigurationOverrideFile>");
232 ps.WriteLine(" <OutputPath>{0}</OutputPath>", 232 ps.WriteLine(" <DefineConstants>{0}</DefineConstants>", conf.Options["CompilerDefines"]);
233 Helper.EndPath(Helper.NormalizePath("bin\\"))); 233 ps.WriteLine(" <DocumentationFile>{0}</DocumentationFile>", Helper.NormalizePath(conf.Options["XmlDocFile"].ToString()));
234 234 ps.WriteLine(" <DebugSymbols>{0}</DebugSymbols>", conf.Options["DebugInformation"]);
235 ps.WriteLine(" <RegisterForComInterop>{0}</RegisterForComInterop>", conf.Options["RegisterComInterop"]); 235 ps.WriteLine(" <FileAlignment>{0}</FileAlignment>", conf.Options["FileAlignment"]);
236 ps.WriteLine(" <RemoveIntegerChecks>{0}</RemoveIntegerChecks>", conf.Options["RemoveIntegerChecks"]); 236 ps.WriteLine(" <Optimize>{0}</Optimize>", conf.Options["OptimizeCode"]);
237 ps.WriteLine(" <TreatWarningsAsErrors>{0}</TreatWarningsAsErrors>", conf.Options["WarningsAsErrors"]); 237 if (project.Type != ProjectType.Web)
238 ps.WriteLine(" <WarningLevel>{0}</WarningLevel>", conf.Options["WarningLevel"]); 238 ps.WriteLine(" <OutputPath>{0}</OutputPath>",
239 ps.WriteLine(" <NoStdLib>{0}</NoStdLib>", conf.Options["NoStdLib"]); 239 Helper.EndPath(Helper.NormalizePath(conf.Options["OutputPath"].ToString())));
240 ps.WriteLine(" <NoWarn>{0}</NoWarn>", conf.Options["SuppressWarnings"]); 240 else
241 ps.WriteLine(" <PlatformTarget>{0}</PlatformTarget>", conf.Platform); 241 ps.WriteLine(" <OutputPath>{0}</OutputPath>",
242 ps.WriteLine(" </PropertyGroup>"); 242 Helper.EndPath(Helper.NormalizePath("bin\\")));
243 } 243
244 244 ps.WriteLine(" <RegisterForComInterop>{0}</RegisterForComInterop>", conf.Options["RegisterComInterop"]);
245 //ps.WriteLine(" </Settings>"); 245 ps.WriteLine(" <RemoveIntegerChecks>{0}</RemoveIntegerChecks>", conf.Options["RemoveIntegerChecks"]);
246 246 ps.WriteLine(" <TreatWarningsAsErrors>{0}</TreatWarningsAsErrors>", conf.Options["WarningsAsErrors"]);
247 Dictionary<ReferenceNode, ProjectNode> projectReferences = new Dictionary<ReferenceNode, ProjectNode>(); 247 ps.WriteLine(" <WarningLevel>{0}</WarningLevel>", conf.Options["WarningLevel"]);
248 List<ReferenceNode> otherReferences = new List<ReferenceNode>(); 248 ps.WriteLine(" <NoStdLib>{0}</NoStdLib>", conf.Options["NoStdLib"]);
249 249 ps.WriteLine(" <NoWarn>{0}</NoWarn>", conf.Options["SuppressWarnings"]);
250 foreach (ReferenceNode refr in project.References) 250 ps.WriteLine(" <PlatformTarget>{0}</PlatformTarget>", conf.Platform);
251 { 251 ps.WriteLine(" </PropertyGroup>");
252 ProjectNode projectNode = FindProjectInSolution(refr.Name, solution); 252 }
253 253
254 if (projectNode == null) 254 //ps.WriteLine(" </Settings>");
255 otherReferences.Add(refr); 255
256 else 256 Dictionary<ReferenceNode, ProjectNode> projectReferences = new Dictionary<ReferenceNode, ProjectNode>();
257 projectReferences.Add(refr, projectNode); 257 List<ReferenceNode> otherReferences = new List<ReferenceNode>();
258 } 258
259 // Assembly References 259 foreach (ReferenceNode refr in project.References)
260 ps.WriteLine(" <ItemGroup>"); 260 {
261 261 ProjectNode projectNode = FindProjectInSolution(refr.Name, solution);
262 foreach (ReferenceNode refr in otherReferences) 262
263 { 263 if (projectNode == null)
264 ps.Write(" <Reference"); 264 otherReferences.Add(refr);
265 ps.Write(" Include=\""); 265 else
266 ps.Write(refr.Name); 266 projectReferences.Add(refr, projectNode);
267 ps.WriteLine("\" >"); 267 }
268 ps.Write(" <Name>"); 268 // Assembly References
269 ps.Write(refr.Name); 269 ps.WriteLine(" <ItemGroup>");
270 ps.WriteLine("</Name>"); 270
271 271 foreach (ReferenceNode refr in otherReferences)
272 if(!String.IsNullOrEmpty(refr.Path)) 272 {
273 { 273 ps.Write(" <Reference");
274 // Use absolute path to assembly (for determining assembly type) 274 ps.Write(" Include=\"");
275 string absolutePath = Path.Combine(project.FullPath, refr.Path); 275 ps.Write(refr.Name);
276 if(File.Exists(Helper.MakeFilePath(absolutePath, refr.Name, "exe"))) { 276 ps.WriteLine("\" >");
277 // Assembly is an executable (exe) 277 ps.Write(" <Name>");
278 ps.WriteLine(" <HintPath>{0}</HintPath>", Helper.MakeFilePath(refr.Path, refr.Name, "exe")); 278 ps.Write(refr.Name);
279 } else if(File.Exists(Helper.MakeFilePath(absolutePath, refr.Name, "dll"))) { 279 ps.WriteLine("</Name>");
280 // Assembly is an library (dll) 280
281 ps.WriteLine(" <HintPath>{0}</HintPath>", Helper.MakeFilePath(refr.Path, refr.Name, "dll")); 281 if(!String.IsNullOrEmpty(refr.Path))
282 } else { 282 {
283 string referencePath = Helper.MakeFilePath(refr.Path, refr.Name, "dll"); 283 // Use absolute path to assembly (for determining assembly type)
284 kernel.Log.Write(LogType.Warning, "Reference \"{0}\": The specified file doesn't exist.", referencePath); 284 string absolutePath = Path.Combine(project.FullPath, refr.Path);
285 ps.WriteLine(" <HintPath>{0}</HintPath>", Helper.MakeFilePath(refr.Path, refr.Name, "dll")); 285 if(File.Exists(Helper.MakeFilePath(absolutePath, refr.Name, "exe"))) {
286 } 286 // Assembly is an executable (exe)
287 } 287 ps.WriteLine(" <HintPath>{0}</HintPath>", Helper.MakeFilePath(refr.Path, refr.Name, "exe"));
288 288 } else if(File.Exists(Helper.MakeFilePath(absolutePath, refr.Name, "dll"))) {
289 ps.WriteLine(" <Private>{0}</Private>", refr.LocalCopy); 289 // Assembly is an library (dll)
290 ps.WriteLine(" </Reference>"); 290 ps.WriteLine(" <HintPath>{0}</HintPath>", Helper.MakeFilePath(refr.Path, refr.Name, "dll"));
291 } 291 } else {
292 ps.WriteLine(" </ItemGroup>"); 292 string referencePath = Helper.MakeFilePath(refr.Path, refr.Name, "dll");
293 293 kernel.Log.Write(LogType.Warning, "Reference \"{0}\": The specified file doesn't exist.", referencePath);
294 //Project References 294 ps.WriteLine(" <HintPath>{0}</HintPath>", Helper.MakeFilePath(refr.Path, refr.Name, "dll"));
295 ps.WriteLine(" <ItemGroup>"); 295 }
296 foreach (KeyValuePair<ReferenceNode, ProjectNode> pair in projectReferences) 296 }
297 { 297
298 ToolInfo tool = tools[pair.Value.Language]; 298 ps.WriteLine(" <Private>{0}</Private>", refr.LocalCopy);
299 if (tools == null) 299 ps.WriteLine(" </Reference>");
300 throw new UnknownLanguageException(); 300 }
301 301 ps.WriteLine(" </ItemGroup>");
302 string path = 302
303 Helper.MakePathRelativeTo(project.FullPath, 303 //Project References
304 Helper.MakeFilePath(pair.Value.FullPath, pair.Value.Name, tool.FileExtension)); 304 ps.WriteLine(" <ItemGroup>");
305 ps.WriteLine(" <ProjectReference Include=\"{0}\">", path); 305 foreach (KeyValuePair<ReferenceNode, ProjectNode> pair in projectReferences)
306 306 {
307 // TODO: Allow reference to visual basic projects 307 ToolInfo tool = tools[pair.Value.Language];
308 ps.WriteLine(" <Name>{0}</Name>", pair.Value.Name); 308 if (tools == null)
309 ps.WriteLine(" <Project>{0}</Project>", pair.Value.Guid.ToString("B").ToUpper()); 309 throw new UnknownLanguageException();
310 ps.WriteLine(" <Package>{0}</Package>", tool.Guid.ToUpper()); 310
311 311 string path =
312 //This is the Copy Local flag in VS 312 Helper.MakePathRelativeTo(project.FullPath,
313 ps.WriteLine(" <Private>{0}</Private>", pair.Key.LocalCopy); 313 Helper.MakeFilePath(pair.Value.FullPath, pair.Value.Name, tool.FileExtension));
314 314 ps.WriteLine(" <ProjectReference Include=\"{0}\">", path);
315 ps.WriteLine(" </ProjectReference>"); 315
316 } 316 // TODO: Allow reference to visual basic projects
317 ps.WriteLine(" </ItemGroup>"); 317 ps.WriteLine(" <Name>{0}</Name>", pair.Value.Name);
318 318 ps.WriteLine(" <Project>{0}</Project>", pair.Value.Guid.ToString("B").ToUpper());
319 // ps.WriteLine(" </Build>"); 319 ps.WriteLine(" <Package>{0}</Package>", tool.Guid.ToUpper());
320 ps.WriteLine(" <ItemGroup>"); 320
321 321 //This is the Copy Local flag in VS
322 // ps.WriteLine(" <Include>"); 322 ps.WriteLine(" <Private>{0}</Private>", pair.Key.LocalCopy);
323 List<string> list = new List<string>(); 323
324 324 ps.WriteLine(" </ProjectReference>");
325 foreach (string path in project.Files) 325 }
326 { 326 ps.WriteLine(" </ItemGroup>");
327 string lower = path.ToLower(); 327
328 if (lower.EndsWith(".resx")) 328 // ps.WriteLine(" </Build>");
329 { 329 ps.WriteLine(" <ItemGroup>");
330 string codebehind = String.Format("{0}.Designer{1}", path.Substring(0, path.LastIndexOf('.')), toolInfo.LanguageExtension); 330
331 if (!list.Contains(codebehind)) 331 // ps.WriteLine(" <Include>");
332 list.Add(codebehind); 332 List<string> list = new List<string>();
333 } 333
334 334 foreach (string path in project.Files)
335 } 335 {
336 336 string lower = path.ToLower();
337 foreach (string filePath in project.Files) 337 if (lower.EndsWith(".resx"))
338 { 338 {
339 // if (file == "Properties\\Bind.Designer.cs") 339 string codebehind = String.Format("{0}.Designer{1}", path.Substring(0, path.LastIndexOf('.')), toolInfo.LanguageExtension);
340 // { 340 if (!list.Contains(codebehind))
341 // Console.WriteLine("Wait a minute!"); 341 list.Add(codebehind);
342 // Console.WriteLine(project.Files.GetSubType(file).ToString()); 342 }
343 // } 343
344 SubType subType = project.Files.GetSubType(filePath); 344 }
345 345
346 // Visual Studio chokes on file names if forward slash is used as a path separator 346
347 // instead of backslash. So we must make sure that all file paths written to the 347 foreach (string filePath in project.Files)
348 // project file use \ as a path separator. 348 {
349 string file = filePath.Replace(@"/", @"\"); 349 // Add the filePath with the destination as the key
350 350 // will use it later to form the copy parameters with Include lists
351 if (subType != SubType.Code && subType != SubType.Settings && subType != SubType.Designer 351 // for each destination
352 && subType != SubType.CodeBehind) 352 if (project.Files.GetBuildAction(filePath) == BuildAction.Copy)
353 { 353 continue;
354 ps.WriteLine(" <EmbeddedResource Include=\"{0}\">", file.Substring(0, file.LastIndexOf('.')) + ".resx"); 354 // if (file == "Properties\\Bind.Designer.cs")
355 ps.WriteLine(" <DependentUpon>{0}</DependentUpon>", Path.GetFileName(file)); 355 // {
356 ps.WriteLine(" <SubType>Designer</SubType>"); 356 // Console.WriteLine("Wait a minute!");
357 ps.WriteLine(" </EmbeddedResource>"); 357 // Console.WriteLine(project.Files.GetSubType(file).ToString());
358 // 358 // }
359 } 359 SubType subType = project.Files.GetSubType(filePath);
360 360
361 if (subType == SubType.Designer) 361 // Visual Studio chokes on file names if forward slash is used as a path separator
362 { 362 // instead of backslash. So we must make sure that all file paths written to the
363 ps.WriteLine(" <EmbeddedResource Include=\"{0}\">", file); 363 // project file use \ as a path separator.
364 364 string file = filePath.Replace(@"/", @"\");
365 string autogen_name = file.Substring(0, file.LastIndexOf('.')) + ".Designer.cs"; 365
366 string dependent_name = filePath.Substring(0, file.LastIndexOf('.')) + ".cs"; 366 if (subType != SubType.Code && subType != SubType.Settings && subType != SubType.Designer
367 367 && subType != SubType.CodeBehind)
368 // Check for a parent .cs file with the same name as this designer file 368 {
369 if (File.Exists(Helper.NormalizePath(dependent_name))) 369 ps.WriteLine(" <EmbeddedResource Include=\"{0}\">", file.Substring(0, file.LastIndexOf('.')) + ".resx");
370 { 370 ps.WriteLine(" <DependentUpon>{0}</DependentUpon>", Path.GetFileName(file));
371 ps.WriteLine(" <DependentUpon>{0}</DependentUpon>", Path.GetFileName(dependent_name)); 371 ps.WriteLine(" <SubType>Designer</SubType>");
372 } 372 ps.WriteLine(" </EmbeddedResource>");
373 else 373 //
374 { 374 }
375 ps.WriteLine(" <Generator>ResXFileCodeGenerator</Generator>"); 375
376 ps.WriteLine(" <LastGenOutput>{0}</LastGenOutput>", Path.GetFileName(autogen_name)); 376 if (subType == SubType.Designer)
377 ps.WriteLine(" <SubType>" + subType + "</SubType>"); 377 {
378 } 378 ps.WriteLine(" <EmbeddedResource Include=\"{0}\">", file);
379 379
380 ps.WriteLine(" </EmbeddedResource>"); 380 string autogen_name = file.Substring(0, file.LastIndexOf('.')) + ".Designer.cs";
381 if (File.Exists(Helper.NormalizePath(autogen_name))) 381 string dependent_name = filePath.Substring(0, file.LastIndexOf('.')) + ".cs";
382 { 382
383 ps.WriteLine(" <Compile Include=\"{0}\">", autogen_name); 383 // Check for a parent .cs file with the same name as this designer file
384 //ps.WriteLine(" <DesignTime>True</DesignTime>"); 384 if (File.Exists(Helper.NormalizePath(dependent_name)))
385 385 {
386 // If a parent .cs file exists, link this autogen file to it. Otherwise link 386 ps.WriteLine(" <DependentUpon>{0}</DependentUpon>", Path.GetFileName(dependent_name));
387 // to the designer file 387 }
388 if (File.Exists(dependent_name)) 388 else
389 { 389 {
390 ps.WriteLine(" <DependentUpon>{0}</DependentUpon>", Path.GetFileName(dependent_name)); 390 ps.WriteLine(" <Generator>ResXFileCodeGenerator</Generator>");
391 } 391 ps.WriteLine(" <LastGenOutput>{0}</LastGenOutput>", Path.GetFileName(autogen_name));
392 else 392 ps.WriteLine(" <SubType>" + subType + "</SubType>");
393 { 393 }
394 ps.WriteLine(" <AutoGen>True</AutoGen>"); 394
395 ps.WriteLine(" <DependentUpon>{0}</DependentUpon>", Path.GetFileName(filePath)); 395 ps.WriteLine(" </EmbeddedResource>");
396 } 396 if (File.Exists(Helper.NormalizePath(autogen_name)))
397 397 {
398 ps.WriteLine(" </Compile>"); 398 ps.WriteLine(" <Compile Include=\"{0}\">", autogen_name);
399 } 399 //ps.WriteLine(" <DesignTime>True</DesignTime>");
400 list.Add(autogen_name); 400
401 } 401 // If a parent .cs file exists, link this autogen file to it. Otherwise link
402 if (subType == SubType.Settings) 402 // to the designer file
403 { 403 if (File.Exists(dependent_name))
404 ps.Write(" <{0} ", project.Files.GetBuildAction(filePath)); 404 {
405 ps.WriteLine("Include=\"{0}\">", file); 405 ps.WriteLine(" <DependentUpon>{0}</DependentUpon>", Path.GetFileName(dependent_name));
406 string fileName = Path.GetFileName(filePath); 406 }
407 if (project.Files.GetBuildAction(filePath) == BuildAction.None) 407 else
408 { 408 {
409 ps.WriteLine(" <Generator>SettingsSingleFileGenerator</Generator>"); 409 ps.WriteLine(" <AutoGen>True</AutoGen>");
410 ps.WriteLine(" <LastGenOutput>{0}</LastGenOutput>", fileName.Substring(0, fileName.LastIndexOf('.')) + ".Designer.cs"); 410 ps.WriteLine(" <DependentUpon>{0}</DependentUpon>", Path.GetFileName(filePath));
411 } 411 }
412 else 412
413 { 413 ps.WriteLine(" </Compile>");
414 ps.WriteLine(" <SubType>Code</SubType>"); 414 }
415 ps.WriteLine(" <AutoGen>True</AutoGen>"); 415 list.Add(autogen_name);
416 ps.WriteLine(" <DesignTimeSharedInput>True</DesignTimeSharedInput>"); 416 }
417 string fileNameShort = fileName.Substring(0, fileName.LastIndexOf('.')); 417 if (subType == SubType.Settings)
418 string fileNameShorter = fileNameShort.Substring(0, fileNameShort.LastIndexOf('.')); 418 {
419 ps.WriteLine(" <DependentUpon>{0}</DependentUpon>", Path.GetFileName(fileNameShorter + ".settings")); 419 ps.Write(" <{0} ", project.Files.GetBuildAction(filePath));
420 } 420 ps.WriteLine("Include=\"{0}\">", file);
421 ps.WriteLine(" </{0}>", project.Files.GetBuildAction(filePath)); 421 string fileName = Path.GetFileName(filePath);
422 } 422 if (project.Files.GetBuildAction(filePath) == BuildAction.None)
423 else if (subType != SubType.Designer) 423 {
424 { 424 ps.WriteLine(" <Generator>SettingsSingleFileGenerator</Generator>");
425 string path = Helper.NormalizePath(file); 425 ps.WriteLine(" <LastGenOutput>{0}</LastGenOutput>", fileName.Substring(0, fileName.LastIndexOf('.')) + ".Designer.cs");
426 string path_lower = path.ToLower(); 426 }
427 427 else
428 if (!list.Contains(filePath)) 428 {
429 { 429 ps.WriteLine(" <SubType>Code</SubType>");
430 ps.Write(" <{0} ", project.Files.GetBuildAction(filePath)); 430 ps.WriteLine(" <AutoGen>True</AutoGen>");
431 431 ps.WriteLine(" <DesignTimeSharedInput>True</DesignTimeSharedInput>");
432 int startPos = 0; 432 string fileNameShort = fileName.Substring(0, fileName.LastIndexOf('.'));
433 if (project.Files.GetPreservePath(filePath)) 433 string fileNameShorter = fileNameShort.Substring(0, fileNameShort.LastIndexOf('.'));
434 { 434 ps.WriteLine(" <DependentUpon>{0}</DependentUpon>", Path.GetFileName(fileNameShorter + ".settings"));
435 while ((@"./\").IndexOf(file.Substring(startPos, 1)) != -1) 435 }
436 startPos++; 436 ps.WriteLine(" </{0}>", project.Files.GetBuildAction(filePath));
437 437 }
438 } 438 else if (subType != SubType.Designer)
439 else 439 {
440 { 440 string path = Helper.NormalizePath(file);
441 startPos = file.LastIndexOf(Path.GetFileName(path)); 441 string path_lower = path.ToLower();
442 } 442
443 443 if (!list.Contains(filePath))
444 // be sure to write out the path with backslashes so VS recognizes 444 {
445 // the file properly. 445 ps.Write(" <{0} ", project.Files.GetBuildAction(filePath));
446 ps.WriteLine("Include=\"{0}\">", file); 446
447 447 int startPos = 0;
448 int last_period_index = file.LastIndexOf('.'); 448 if (project.Files.GetPreservePath(filePath))
449 string short_file_name = file.Substring(0, last_period_index); 449 {
450 string extension = Path.GetExtension(path); 450 while ((@"./\").IndexOf(file.Substring(startPos, 1)) != -1)
451 // make this upper case, so that when File.Exists tests for the 451 startPos++;
452 // existence of a designer file on a case-sensitive platform, 452
453 // it is correctly identified. 453 }
454 string designer_format = string.Format(".Designer{0}", extension); 454 else
455 455 {
456 if (path_lower.EndsWith(designer_format.ToLowerInvariant())) 456 startPos = file.LastIndexOf(Path.GetFileName(path));
457 { 457 }
458 int designer_index = path.IndexOf(designer_format); 458
459 string file_name = path.Substring(0, designer_index); 459 // be sure to write out the path with backslashes so VS recognizes
460 460 // the file properly.
461 // There are two corrections to the next lines: 461 ps.WriteLine("Include=\"{0}\">", file);
462 // 1. Fix the connection between a designer file and a form 462
463 // or usercontrol that don't have an associated resx file. 463 int last_period_index = file.LastIndexOf('.');
464 // 2. Connect settings files to associated designer files. 464 string short_file_name = (last_period_index >= 0)
465 if (File.Exists(file_name + extension)) 465 ? file.Substring(0, last_period_index)
466 ps.WriteLine(" <DependentUpon>{0}</DependentUpon>", Path.GetFileName(file_name + extension)); 466 : file;
467 else if (File.Exists(file_name + ".resx")) 467 string extension = Path.GetExtension(path);
468 ps.WriteLine(" <DependentUpon>{0}</DependentUpon>", Path.GetFileName(file_name + ".resx")); 468 // make this upper case, so that when File.Exists tests for the
469 else if (File.Exists(file_name + ".settings")) 469 // existence of a designer file on a case-sensitive platform,
470 { 470 // it is correctly identified.
471 ps.WriteLine(" <DependentUpon>{0}</DependentUpon>", Path.GetFileName(file_name + ".settings")); 471 string designer_format = string.Format(".Designer{0}", extension);
472 ps.WriteLine(" <AutoGen>True</AutoGen>"); 472
473 ps.WriteLine(" <DesignTimeSharedInput>True</DesignTimeSharedInput>"); 473 if (path_lower.EndsWith(designer_format.ToLowerInvariant()))
474 } 474 {
475 } 475 int designer_index = path.IndexOf(designer_format);
476 else if (subType == SubType.CodeBehind) 476 string file_name = path.Substring(0, designer_index);
477 { 477
478 ps.WriteLine(" <DependentUpon>{0}</DependentUpon>", Path.GetFileName(short_file_name)); 478 // There are two corrections to the next lines:
479 } 479 // 1. Fix the connection between a designer file and a form
480 if (project.Files.GetIsLink(filePath)) 480 // or usercontrol that don't have an associated resx file.
481 { 481 // 2. Connect settings files to associated designer files.
482 string alias = project.Files.GetLinkPath(filePath); 482 if (File.Exists(file_name + extension))
483 alias += file.Substring(startPos); 483 ps.WriteLine(" <DependentUpon>{0}</DependentUpon>", Path.GetFileName(file_name + extension));
484 alias = Helper.NormalizePath(alias); 484 else if (File.Exists(file_name + ".resx"))
485 ps.WriteLine(" <Link>{0}</Link>", alias); 485 ps.WriteLine(" <DependentUpon>{0}</DependentUpon>", Path.GetFileName(file_name + ".resx"));
486 } 486 else if (File.Exists(file_name + ".settings"))
487 else if (project.Files.GetBuildAction(filePath) != BuildAction.None) 487 {
488 { 488 ps.WriteLine(" <DependentUpon>{0}</DependentUpon>", Path.GetFileName(file_name + ".settings"));
489 if (project.Files.GetBuildAction(filePath) != BuildAction.EmbeddedResource) 489 ps.WriteLine(" <AutoGen>True</AutoGen>");
490 { 490 ps.WriteLine(" <DesignTimeSharedInput>True</DesignTimeSharedInput>");
491 ps.WriteLine(" <SubType>{0}</SubType>", subType); 491 }
492 } 492 }
493 } 493 else if (subType == SubType.CodeBehind)
494 494 {
495 if (project.Files.GetCopyToOutput(filePath) != CopyToOutput.Never) 495 ps.WriteLine(" <DependentUpon>{0}</DependentUpon>", Path.GetFileName(short_file_name));
496 { 496 }
497 ps.WriteLine(" <CopyToOutputDirectory>{0}</CopyToOutputDirectory>", project.Files.GetCopyToOutput(filePath)); 497 if (project.Files.GetIsLink(filePath))
498 } 498 {
499 499 string alias = project.Files.GetLinkPath(filePath);
500 ps.WriteLine(" </{0}>", project.Files.GetBuildAction(filePath)); 500 alias += file.Substring(startPos);
501 } 501 alias = Helper.NormalizePath(alias);
502 } 502 ps.WriteLine(" <Link>{0}</Link>", alias);
503 } 503 }
504 504 else if (project.Files.GetBuildAction(filePath) != BuildAction.None)
505 ps.WriteLine(" </ItemGroup>"); 505 {
506 ps.WriteLine(" <Import Project=\"" + toolInfo.ImportProject + "\" />"); 506 if (project.Files.GetBuildAction(filePath) != BuildAction.EmbeddedResource)
507 ps.WriteLine(" <PropertyGroup>"); 507 {
508 ps.WriteLine(" <PreBuildEvent>"); 508 ps.WriteLine(" <SubType>{0}</SubType>", subType);
509 ps.WriteLine(" </PreBuildEvent>"); 509 }
510 ps.WriteLine(" <PostBuildEvent>"); 510 }
511 ps.WriteLine(" </PostBuildEvent>"); 511
512 ps.WriteLine(" </PropertyGroup>"); 512 if (project.Files.GetCopyToOutput(filePath) != CopyToOutput.Never)
513 ps.WriteLine("</Project>"); 513 {
514 } 514 ps.WriteLine(" <CopyToOutputDirectory>{0}</CopyToOutputDirectory>", project.Files.GetCopyToOutput(filePath));
515 #endregion 515 }
516 516
517 #region User File 517 ps.WriteLine(" </{0}>", project.Files.GetBuildAction(filePath));
518 518 }
519 ps = new StreamWriter(projectFile + ".user"); 519 }
520 using (ps) 520 }
521 { 521 ps.WriteLine(" </ItemGroup>");
522 // Get the first configuration from the project. 522
523 ConfigurationNode firstConfiguration = null; 523 /*
524 524 * Copy Task
525 if (project.Configurations.Count > 0) 525 *
526 { 526 */
527 firstConfiguration = project.Configurations[0]; 527 if ( project.Files.CopyFiles > 0 ) {
528 } 528
529 529 Dictionary<string, string> IncludeTags = new Dictionary<string, string>();
530 ps.WriteLine("<Project xmlns=\"http://schemas.microsoft.com/developer/msbuild/2003\">"); 530 int TagCount = 0;
531 //ps.WriteLine( "<VisualStudioProject>" ); 531
532 //ps.WriteLine(" <{0}>", toolInfo.XMLTag); 532 // Handle Copy tasks
533 //ps.WriteLine(" <Build>"); 533 ps.WriteLine(" <ItemGroup>");
534 ps.WriteLine(" <PropertyGroup>"); 534 foreach (string destPath in project.Files.Destinations)
535 //ps.WriteLine(" <Settings ReferencePath=\"{0}\">", MakeRefPath(project)); 535 {
536 536 string tag = "FilesToCopy_" + TagCount.ToString("0000");
537 if (firstConfiguration != null) 537
538 { 538 ps.WriteLine(" <{0} Include=\"{1}\" />", tag, String.Join(";", project.Files.SourceFiles(destPath)));
539 ps.WriteLine(" <Configuration Condition=\" '$(Configuration)' == '' \">{0}</Configuration>", firstConfiguration.Name); 539 IncludeTags.Add(destPath, tag);
540 ps.WriteLine(" <Platform Condition=\" '$(Platform)' == '' \">{0}</Platform>", firstConfiguration.Platform); 540 TagCount++;
541 } 541 }
542 542
543 ps.WriteLine(" <ReferencePath>{0}</ReferencePath>", MakeRefPath(project)); 543 ps.WriteLine(" </ItemGroup>");
544 ps.WriteLine(" <LastOpenVersion>{0}</LastOpenVersion>", ProductVersion); 544
545 ps.WriteLine(" <ProjectView>ProjectFiles</ProjectView>"); 545 ps.WriteLine(" <Target Name=\"CopyFiles\">");
546 ps.WriteLine(" <ProjectTrust>0</ProjectTrust>"); 546
547 ps.WriteLine(" </PropertyGroup>"); 547 foreach (string destPath in project.Files.Destinations)
548 foreach (ConfigurationNode conf in project.Configurations) 548 {
549 { 549 ps.WriteLine(" <Copy SourceFiles=\"@({0})\" DestinationFolder=\"{1}\" />",
550 ps.Write(" <PropertyGroup"); 550 IncludeTags[destPath], destPath);
551 ps.Write(" Condition = \" '$(Configuration)|$(Platform)' == '{0}|{1}' \"", conf.Name, conf.Platform); 551 }
552 ps.WriteLine(" />"); 552
553 } 553 ps.WriteLine(" </Target>");
554 ps.WriteLine("</Project>"); 554 }
555 } 555
556 #endregion 556 ps.WriteLine(" <Import Project=\"" + toolInfo.ImportProject + "\" />");
557 557 ps.WriteLine(" <PropertyGroup>");
558 kernel.CurrentWorkingDirectory.Pop(); 558 ps.WriteLine(" <PreBuildEvent>");
559 } 559 ps.WriteLine(" </PreBuildEvent>");
560 560 ps.WriteLine(" <PostBuildEvent>");
561 private void WriteSolution(SolutionNode solution, bool writeSolutionToDisk) 561 ps.WriteLine(" </PostBuildEvent>");
562 { 562 ps.WriteLine(" </PropertyGroup>");
563 kernel.Log.Write("Creating {0} solution and project files", VersionName); 563 ps.WriteLine("</Project>");
564 564 }
565 foreach (SolutionNode child in solution.Solutions) 565 #endregion
566 { 566
567 kernel.Log.Write("...Creating folder: {0}", child.Name); 567 #region User File
568 WriteSolution(child, false); 568
569 } 569 ps = new StreamWriter(projectFile + ".user");
570 570 using (ps)
571 foreach (ProjectNode project in solution.Projects) 571 {
572 { 572 // Get the first configuration from the project.
573 kernel.Log.Write("...Creating project: {0}", project.Name); 573 ConfigurationNode firstConfiguration = null;
574 WriteProject(solution, project); 574
575 } 575 if (project.Configurations.Count > 0)
576 576 {
577 foreach (DatabaseProjectNode project in solution.DatabaseProjects) 577 firstConfiguration = project.Configurations[0];
578 { 578 }
579 kernel.Log.Write("...Creating database project: {0}", project.Name); 579
580 WriteDatabaseProject(solution, project); 580 ps.WriteLine("<Project xmlns=\"http://schemas.microsoft.com/developer/msbuild/2003\">");
581 } 581 //ps.WriteLine( "<VisualStudioProject>" );
582 582 //ps.WriteLine(" <{0}>", toolInfo.XMLTag);
583 if (writeSolutionToDisk) // only write main solution 583 //ps.WriteLine(" <Build>");
584 { 584 ps.WriteLine(" <PropertyGroup>");
585 kernel.Log.Write(""); 585 //ps.WriteLine(" <Settings ReferencePath=\"{0}\">", MakeRefPath(project));
586 string solutionFile = Helper.MakeFilePath(solution.FullPath, solution.Name, "sln"); 586
587 587 if (firstConfiguration != null)
588 using (StreamWriter ss = new StreamWriter(solutionFile)) 588 {
589 { 589 ps.WriteLine(" <Configuration Condition=\" '$(Configuration)' == '' \">{0}</Configuration>", firstConfiguration.Name);
590 kernel.CurrentWorkingDirectory.Push(); 590 ps.WriteLine(" <Platform Condition=\" '$(Platform)' == '' \">{0}</Platform>", firstConfiguration.Platform);
591 Helper.SetCurrentDir(Path.GetDirectoryName(solutionFile)); 591 }
592 592
593 ss.WriteLine("Microsoft Visual Studio Solution File, Format Version {0}", SolutionVersion); 593 ps.WriteLine(" <ReferencePath>{0}</ReferencePath>", MakeRefPath(project));
594 ss.WriteLine(SolutionTag); 594 ps.WriteLine(" <LastOpenVersion>{0}</LastOpenVersion>", ProductVersion);
595 595 ps.WriteLine(" <ProjectView>ProjectFiles</ProjectView>");
596 WriteProjectDeclarations(ss, solution, solution); 596 ps.WriteLine(" <ProjectTrust>0</ProjectTrust>");
597 597 ps.WriteLine(" </PropertyGroup>");
598 ss.WriteLine("Global"); 598 foreach (ConfigurationNode conf in project.Configurations)
599 599 {
600 ss.WriteLine("\tGlobalSection(SolutionConfigurationPlatforms) = preSolution"); 600 ps.Write(" <PropertyGroup");
601 foreach (ConfigurationNode conf in solution.Configurations) 601 ps.Write(" Condition = \" '$(Configuration)|$(Platform)' == '{0}|{1}' \"", conf.Name, conf.Platform);
602 { 602 ps.WriteLine(" />");
603 ss.WriteLine("\t\t{0} = {0}", conf.NameAndPlatform); 603 }
604 } 604 ps.WriteLine("</Project>");
605 ss.WriteLine("\tEndGlobalSection"); 605 }
606 606 #endregion
607 ss.WriteLine("\tGlobalSection(ProjectConfigurationPlatforms) = postSolution"); 607
608 WriteConfigurationLines(solution.Configurations, solution, ss); 608 kernel.CurrentWorkingDirectory.Pop();
609 ss.WriteLine("\tEndGlobalSection"); 609 }
610 610
611 if (solution.Solutions.Count > 0) 611 private void WriteSolution(SolutionNode solution, bool writeSolutionToDisk)
612 { 612 {
613 ss.WriteLine("\tGlobalSection(NestedProjects) = preSolution"); 613 kernel.Log.Write("Creating {0} solution and project files", VersionName);
614 foreach (SolutionNode embeddedSolution in solution.Solutions) 614
615 { 615 foreach (SolutionNode child in solution.Solutions)
616 WriteNestedProjectMap(ss, embeddedSolution); 616 {
617 } 617 kernel.Log.Write("...Creating folder: {0}", child.Name);
618 ss.WriteLine("\tEndGlobalSection"); 618 WriteSolution(child, false);
619 } 619 }
620 620
621 ss.WriteLine("EndGlobal"); 621 foreach (ProjectNode project in solution.Projects)
622 } 622 {
623 623 kernel.Log.Write("...Creating project: {0}", project.Name);
624 kernel.CurrentWorkingDirectory.Pop(); 624 WriteProject(solution, project);
625 } 625 }
626 } 626
627 627 foreach (DatabaseProjectNode project in solution.DatabaseProjects)
628 private void WriteProjectDeclarations(TextWriter writer, SolutionNode actualSolution, SolutionNode embeddedSolution) 628 {
629 { 629 kernel.Log.Write("...Creating database project: {0}", project.Name);
630 foreach (SolutionNode childSolution in embeddedSolution.Solutions) 630 WriteDatabaseProject(solution, project);
631 { 631 }
632 WriteEmbeddedSolution(writer, childSolution); 632
633 WriteProjectDeclarations(writer, actualSolution, childSolution); 633 if (writeSolutionToDisk) // only write main solution
634 } 634 {
635 635 kernel.Log.Write("");
636 foreach (ProjectNode project in embeddedSolution.Projects) 636 string solutionFile = Helper.MakeFilePath(solution.FullPath, solution.Name, "sln");
637 { 637
638 WriteProject(actualSolution, writer, project); 638 using (StreamWriter ss = new StreamWriter(solutionFile))
639 } 639 {
640 640 kernel.CurrentWorkingDirectory.Push();
641 foreach (DatabaseProjectNode dbProject in embeddedSolution.DatabaseProjects) 641 Helper.SetCurrentDir(Path.GetDirectoryName(solutionFile));
642 { 642
643 WriteProject(actualSolution, writer, dbProject); 643 ss.WriteLine("Microsoft Visual Studio Solution File, Format Version {0}", SolutionVersion);
644 } 644 ss.WriteLine(SolutionTag);
645 645
646 if (actualSolution.Guid == embeddedSolution.Guid) 646 WriteProjectDeclarations(ss, solution, solution);
647 { 647
648 WriteSolutionFiles(actualSolution, writer); 648 ss.WriteLine("Global");
649 } 649
650 } 650 ss.WriteLine("\tGlobalSection(SolutionConfigurationPlatforms) = preSolution");
651 651 foreach (ConfigurationNode conf in solution.Configurations)
652 private static void WriteNestedProjectMap(TextWriter writer, SolutionNode embeddedSolution) 652 {
653 { 653 ss.WriteLine("\t\t{0} = {0}", conf.NameAndPlatform);
654 foreach (ProjectNode project in embeddedSolution.Projects) 654 }
655 { 655 ss.WriteLine("\tEndGlobalSection");
656 WriteNestedProject(writer, embeddedSolution, project.Guid); 656
657 } 657 ss.WriteLine("\tGlobalSection(ProjectConfigurationPlatforms) = postSolution");
658 658 WriteConfigurationLines(solution.Configurations, solution, ss);
659 foreach (DatabaseProjectNode dbProject in embeddedSolution.DatabaseProjects) 659 ss.WriteLine("\tEndGlobalSection");
660 { 660
661 WriteNestedProject(writer, embeddedSolution, dbProject.Guid); 661 if (solution.Solutions.Count > 0)
662 } 662 {
663 663 ss.WriteLine("\tGlobalSection(NestedProjects) = preSolution");
664 foreach (SolutionNode child in embeddedSolution.Solutions) 664 foreach (SolutionNode embeddedSolution in solution.Solutions)
665 { 665 {
666 WriteNestedProject(writer, embeddedSolution, child.Guid); 666 WriteNestedProjectMap(ss, embeddedSolution);
667 WriteNestedProjectMap(writer, child); 667 }
668 } 668 ss.WriteLine("\tEndGlobalSection");
669 } 669 }
670 670
671 private static void WriteNestedProject(TextWriter writer, SolutionNode solution, Guid projectGuid) 671 ss.WriteLine("EndGlobal");
672 { 672 }
673 WriteNestedFolder(writer, solution.Guid, projectGuid); 673
674 } 674 kernel.CurrentWorkingDirectory.Pop();
675 675 }
676 private static void WriteNestedFolder(TextWriter writer, Guid parentGuid, Guid childGuid) 676 }
677 { 677
678 writer.WriteLine("\t\t{0} = {1}", 678 private void WriteProjectDeclarations(TextWriter writer, SolutionNode actualSolution, SolutionNode embeddedSolution)
679 childGuid.ToString("B").ToUpper(), 679 {
680 parentGuid.ToString("B").ToUpper()); 680 foreach (SolutionNode childSolution in embeddedSolution.Solutions)
681 } 681 {
682 682 WriteEmbeddedSolution(writer, childSolution);
683 private static void WriteConfigurationLines(IEnumerable<ConfigurationNode> configurations, SolutionNode solution, TextWriter ss) 683 WriteProjectDeclarations(writer, actualSolution, childSolution);
684 { 684 }
685 foreach (ProjectNode project in solution.Projects) 685
686 { 686 foreach (ProjectNode project in embeddedSolution.Projects)
687 foreach (ConfigurationNode conf in configurations) 687 {
688 { 688 WriteProject(actualSolution, writer, project);
689 ss.WriteLine("\t\t{0}.{1}.ActiveCfg = {1}", 689 }
690 project.Guid.ToString("B").ToUpper(), 690
691 conf.NameAndPlatform); 691 foreach (DatabaseProjectNode dbProject in embeddedSolution.DatabaseProjects)
692 692 {
693 ss.WriteLine("\t\t{0}.{1}.Build.0 = {1}", 693 WriteProject(actualSolution, writer, dbProject);
694 project.Guid.ToString("B").ToUpper(), 694 }
695 conf.NameAndPlatform); 695
696 } 696 if (actualSolution.Guid == embeddedSolution.Guid)
697 } 697 {
698 698 WriteSolutionFiles(actualSolution, writer);
699 foreach (SolutionNode child in solution.Solutions) 699 }
700 { 700 }
701 WriteConfigurationLines(configurations, child, ss); 701
702 } 702 private static void WriteNestedProjectMap(TextWriter writer, SolutionNode embeddedSolution)
703 } 703 {
704 704 foreach (ProjectNode project in embeddedSolution.Projects)
705 private void WriteSolutionFiles(SolutionNode solution, TextWriter ss) 705 {
706 { 706 WriteNestedProject(writer, embeddedSolution, project.Guid);
707 if(solution.Files != null && solution.Files.Count > 0) 707 }
708 WriteProject(ss, "Folder", solution.Guid, "Solution Files", "Solution Files", solution.Files); 708
709 } 709 foreach (DatabaseProjectNode dbProject in embeddedSolution.DatabaseProjects)
710 710 {
711 private void WriteEmbeddedSolution(TextWriter writer, SolutionNode embeddedSolution) 711 WriteNestedProject(writer, embeddedSolution, dbProject.Guid);
712 { 712 }
713 WriteProject(writer, "Folder", embeddedSolution.Guid, embeddedSolution.Name, embeddedSolution.Name, embeddedSolution.Files); 713
714 } 714 foreach (SolutionNode child in embeddedSolution.Solutions)
715 715 {
716 private void WriteProject(SolutionNode solution, TextWriter ss, ProjectNode project) 716 WriteNestedProject(writer, embeddedSolution, child.Guid);
717 { 717 WriteNestedProjectMap(writer, child);
718 WriteProject(ss, solution, project.Language, project.Guid, project.Name, project.FullPath); 718 }
719 } 719 }
720 720
721 private void WriteProject(SolutionNode solution, TextWriter ss, DatabaseProjectNode dbProject) 721 private static void WriteNestedProject(TextWriter writer, SolutionNode solution, Guid projectGuid)
722 { 722 {
723 if (solution.Files != null && solution.Files.Count > 0) 723 WriteNestedFolder(writer, solution.Guid, projectGuid);
724 WriteProject(ss, solution, "Database", dbProject.Guid, dbProject.Name, dbProject.FullPath); 724 }
725 } 725
726 726 private static void WriteNestedFolder(TextWriter writer, Guid parentGuid, Guid childGuid)
727 const string ProjectDeclarationBeginFormat = "Project(\"{0}\") = \"{1}\", \"{2}\", \"{3}\""; 727 {
728 const string ProjectDeclarationEndFormat = "EndProject"; 728 writer.WriteLine("\t\t{0} = {1}",
729 729 childGuid.ToString("B").ToUpper(),
730 private void WriteProject(TextWriter ss, SolutionNode solution, string language, Guid guid, string name, string projectFullPath) 730 parentGuid.ToString("B").ToUpper());
731 { 731 }
732 if (!tools.ContainsKey(language)) 732
733 throw new UnknownLanguageException("Unknown .NET language: " + language); 733 private static void WriteConfigurationLines(IEnumerable<ConfigurationNode> configurations, SolutionNode solution, TextWriter ss)
734 734 {
735 ToolInfo toolInfo = tools[language]; 735 foreach (ProjectNode project in solution.Projects)
736 736 {
737 string path = Helper.MakePathRelativeTo(solution.FullPath, projectFullPath); 737 foreach (ConfigurationNode conf in configurations)
738 738 {
739 path = Helper.MakeFilePath(path, name, toolInfo.FileExtension); 739 ss.WriteLine("\t\t{0}.{1}.ActiveCfg = {1}",
740 740 project.Guid.ToString("B").ToUpper(),
741 WriteProject(ss, language, guid, name, path); 741 conf.NameAndPlatform);
742 } 742
743 743 ss.WriteLine("\t\t{0}.{1}.Build.0 = {1}",
744 private void WriteProject(TextWriter writer, string language, Guid projectGuid, string name, string location) 744 project.Guid.ToString("B").ToUpper(),
745 { 745 conf.NameAndPlatform);
746 WriteProject(writer, language, projectGuid, name, location, null); 746 }
747 } 747 }
748 748
749 private void WriteProject(TextWriter writer, string language, Guid projectGuid, string name, string location, FilesNode files) 749 foreach (SolutionNode child in solution.Solutions)
750 { 750 {
751 if (!tools.ContainsKey(language)) 751 WriteConfigurationLines(configurations, child, ss);
752 throw new UnknownLanguageException("Unknown .NET language: " + language); 752 }
753 753 }
754 ToolInfo toolInfo = tools[language]; 754
755 755 private void WriteSolutionFiles(SolutionNode solution, TextWriter ss)
756 writer.WriteLine(ProjectDeclarationBeginFormat, 756 {
757 toolInfo.Guid, 757 if(solution.Files != null && solution.Files.Count > 0)
758 name, 758 WriteProject(ss, "Folder", solution.Guid, "Solution Files", "Solution Files", solution.Files);
759 location, 759 }
760 projectGuid.ToString("B").ToUpper()); 760
761 761 private void WriteEmbeddedSolution(TextWriter writer, SolutionNode embeddedSolution)
762 if (files != null) 762 {
763 { 763 WriteProject(writer, "Folder", embeddedSolution.Guid, embeddedSolution.Name, embeddedSolution.Name, embeddedSolution.Files);
764 writer.WriteLine("\tProjectSection(SolutionItems) = preProject"); 764 }
765 765
766 foreach (string file in files) 766 private void WriteProject(SolutionNode solution, TextWriter ss, ProjectNode project)
767 writer.WriteLine("\t\t{0} = {0}", file); 767 {
768 768 WriteProject(ss, solution, project.Language, project.Guid, project.Name, project.FullPath);
769 writer.WriteLine("\tEndProjectSection"); 769 }
770 } 770
771 771 private void WriteProject(SolutionNode solution, TextWriter ss, DatabaseProjectNode dbProject)
772 writer.WriteLine(ProjectDeclarationEndFormat); 772 {
773 } 773 if (solution.Files != null && solution.Files.Count > 0)
774 774 WriteProject(ss, solution, "Database", dbProject.Guid, dbProject.Name, dbProject.FullPath);
775 private void WriteDatabaseProject(SolutionNode solution, DatabaseProjectNode project) 775 }
776 { 776
777 string projectFile = Helper.MakeFilePath(project.FullPath, project.Name, "dbp"); 777 const string ProjectDeclarationBeginFormat = "Project(\"{0}\") = \"{1}\", \"{2}\", \"{3}\"";
778 IndentedTextWriter ps = new IndentedTextWriter(new StreamWriter(projectFile), " "); 778 const string ProjectDeclarationEndFormat = "EndProject";
779 779
780 kernel.CurrentWorkingDirectory.Push(); 780 private void WriteProject(TextWriter ss, SolutionNode solution, string language, Guid guid, string name, string projectFullPath)
781 781 {
782 Helper.SetCurrentDir(Path.GetDirectoryName(projectFile)); 782 if (!tools.ContainsKey(language))
783 783 throw new UnknownLanguageException("Unknown .NET language: " + language);
784 using (ps) 784
785 { 785 ToolInfo toolInfo = tools[language];
786 ps.WriteLine("# Microsoft Developer Studio Project File - Database Project"); 786
787 ps.WriteLine("Begin DataProject = \"{0}\"", project.Name); 787 string path = Helper.MakePathRelativeTo(solution.FullPath, projectFullPath);
788 ps.Indent++; 788
789 ps.WriteLine("MSDTVersion = \"80\""); 789 path = Helper.MakeFilePath(path, name, toolInfo.FileExtension);
790 // TODO: Use the project.Files property 790
791 if (ContainsSqlFiles(Path.GetDirectoryName(projectFile))) 791 WriteProject(ss, language, guid, name, path);
792 WriteDatabaseFoldersAndFiles(ps, Path.GetDirectoryName(projectFile)); 792 }
793 793
794 ps.WriteLine("Begin DBRefFolder = \"Database References\""); 794 private void WriteProject(TextWriter writer, string language, Guid projectGuid, string name, string location)
795 ps.Indent++; 795 {
796 foreach (DatabaseReferenceNode reference in project.References) 796 WriteProject(writer, language, projectGuid, name, location, null);
797 { 797 }
798 ps.WriteLine("Begin DBRefNode = \"{0}\"", reference.Name); 798
799 ps.Indent++; 799 private void WriteProject(TextWriter writer, string language, Guid projectGuid, string name, string location, FilesNode files)
800 ps.WriteLine("ConnectStr = \"{0}\"", reference.ConnectionString); 800 {
801 ps.WriteLine("Provider = \"{0}\"", reference.ProviderId.ToString("B").ToUpper()); 801 if (!tools.ContainsKey(language))
802 //ps.WriteLine("Colorizer = 5"); 802 throw new UnknownLanguageException("Unknown .NET language: " + language);
803 ps.Indent--; 803
804 ps.WriteLine("End"); 804 ToolInfo toolInfo = tools[language];
805 } 805
806 ps.Indent--; 806 writer.WriteLine(ProjectDeclarationBeginFormat,
807 ps.WriteLine("End"); 807 toolInfo.Guid,
808 ps.Indent--; 808 name,
809 ps.WriteLine("End"); 809 location,
810 810 projectGuid.ToString("B").ToUpper());
811 ps.Flush(); 811
812 } 812 if (files != null)
813 813 {
814 kernel.CurrentWorkingDirectory.Pop(); 814 writer.WriteLine("\tProjectSection(SolutionItems) = preProject");
815 } 815
816 816 foreach (string file in files)
817 private static bool ContainsSqlFiles(string folder) 817 writer.WriteLine("\t\t{0} = {0}", file);
818 { 818
819 if(Directory.GetFiles(folder, "*.sql").Length > 0) 819 writer.WriteLine("\tEndProjectSection");
820 return true; // if the folder contains 1 .sql file, that's good enough 820 }
821 821
822 foreach (string child in Directory.GetDirectories(folder)) 822 writer.WriteLine(ProjectDeclarationEndFormat);
823 { 823 }
824 if (ContainsSqlFiles(child)) 824
825 return true; // if 1 child folder contains a .sql file, still good enough 825 private void WriteDatabaseProject(SolutionNode solution, DatabaseProjectNode project)
826 } 826 {
827 827 string projectFile = Helper.MakeFilePath(project.FullPath, project.Name, "dbp");
828 return false; 828 IndentedTextWriter ps = new IndentedTextWriter(new StreamWriter(projectFile), " ");
829 } 829
830 830 kernel.CurrentWorkingDirectory.Push();
831 private static void WriteDatabaseFoldersAndFiles(IndentedTextWriter writer, string folder) 831
832 { 832 Helper.SetCurrentDir(Path.GetDirectoryName(projectFile));
833 foreach (string child in Directory.GetDirectories(folder)) 833
834 { 834 using (ps)
835 if (ContainsSqlFiles(child)) 835 {
836 { 836 ps.WriteLine("# Microsoft Developer Studio Project File - Database Project");
837 writer.WriteLine("Begin Folder = \"{0}\"", Path.GetFileName(child)); 837 ps.WriteLine("Begin DataProject = \"{0}\"", project.Name);
838 writer.Indent++; 838 ps.Indent++;
839 WriteDatabaseFoldersAndFiles(writer, child); 839 ps.WriteLine("MSDTVersion = \"80\"");
840 writer.Indent--; 840 // TODO: Use the project.Files property
841 writer.WriteLine("End"); 841 if (ContainsSqlFiles(Path.GetDirectoryName(projectFile)))
842 } 842 WriteDatabaseFoldersAndFiles(ps, Path.GetDirectoryName(projectFile));
843 } 843
844 foreach (string file in Directory.GetFiles(folder, "*.sql")) 844 ps.WriteLine("Begin DBRefFolder = \"Database References\"");
845 { 845 ps.Indent++;
846 writer.WriteLine("Script = \"{0}\"", Path.GetFileName(file)); 846 foreach (DatabaseReferenceNode reference in project.References)
847 } 847 {
848 } 848 ps.WriteLine("Begin DBRefNode = \"{0}\"", reference.Name);
849 849 ps.Indent++;
850 private void CleanProject(ProjectNode project) 850 ps.WriteLine("ConnectStr = \"{0}\"", reference.ConnectionString);
851 { 851 ps.WriteLine("Provider = \"{0}\"", reference.ProviderId.ToString("B").ToUpper());
852 kernel.Log.Write("...Cleaning project: {0}", project.Name); 852 //ps.WriteLine("Colorizer = 5");
853 853 ps.Indent--;
854 ToolInfo toolInfo = tools[project.Language]; 854 ps.WriteLine("End");
855 string projectFile = Helper.MakeFilePath(project.FullPath, project.Name, toolInfo.FileExtension); 855 }
856 string userFile = projectFile + ".user"; 856 ps.Indent--;
857 857 ps.WriteLine("End");
858 Helper.DeleteIfExists(projectFile); 858 ps.Indent--;
859 Helper.DeleteIfExists(userFile); 859 ps.WriteLine("End");
860 } 860
861 861 ps.Flush();
862 private void CleanSolution(SolutionNode solution) 862 }
863 { 863
864 kernel.Log.Write("Cleaning {0} solution and project files", VersionName, solution.Name); 864 kernel.CurrentWorkingDirectory.Pop();
865 865 }
866 string slnFile = Helper.MakeFilePath(solution.FullPath, solution.Name, "sln"); 866
867 string suoFile = Helper.MakeFilePath(solution.FullPath, solution.Name, "suo"); 867 private static bool ContainsSqlFiles(string folder)
868 868 {
869 Helper.DeleteIfExists(slnFile); 869 if(Directory.GetFiles(folder, "*.sql").Length > 0)
870 Helper.DeleteIfExists(suoFile); 870 return true; // if the folder contains 1 .sql file, that's good enough
871 871
872 foreach (ProjectNode project in solution.Projects) 872 foreach (string child in Directory.GetDirectories(folder))
873 { 873 {
874 CleanProject(project); 874 if (ContainsSqlFiles(child))
875 } 875 return true; // if 1 child folder contains a .sql file, still good enough
876 876 }
877 kernel.Log.Write(""); 877
878 } 878 return false;
879 879 }
880 #endregion 880
881 881 private static void WriteDatabaseFoldersAndFiles(IndentedTextWriter writer, string folder)
882 #region ITarget Members 882 {
883 883 foreach (string child in Directory.GetDirectories(folder))
884 /// <summary> 884 {
885 /// Writes the specified kern. 885 if (ContainsSqlFiles(child))
886 /// </summary> 886 {
887 /// <param name="kern">The kern.</param> 887 writer.WriteLine("Begin Folder = \"{0}\"", Path.GetFileName(child));
888 public virtual void Write(Kernel kern) 888 writer.Indent++;
889 { 889 WriteDatabaseFoldersAndFiles(writer, child);
890 if (kern == null) 890 writer.Indent--;
891 { 891 writer.WriteLine("End");
892 throw new ArgumentNullException("kern"); 892 }
893 } 893 }
894 kernel = kern; 894 foreach (string file in Directory.GetFiles(folder, "*.sql"))
895 foreach (SolutionNode sol in kernel.Solutions) 895 {
896 { 896 writer.WriteLine("Script = \"{0}\"", Path.GetFileName(file));
897 WriteSolution(sol, true); 897 }
898 } 898 }
899 kernel = null; 899
900 } 900 private void CleanProject(ProjectNode project)
901 901 {
902 /// <summary> 902 kernel.Log.Write("...Cleaning project: {0}", project.Name);
903 /// Cleans the specified kern. 903
904 /// </summary> 904 ToolInfo toolInfo = tools[project.Language];
905 /// <param name="kern">The kern.</param> 905 string projectFile = Helper.MakeFilePath(project.FullPath, project.Name, toolInfo.FileExtension);
906 public virtual void Clean(Kernel kern) 906 string userFile = projectFile + ".user";
907 { 907
908 if (kern == null) 908 Helper.DeleteIfExists(projectFile);
909 { 909 Helper.DeleteIfExists(userFile);
910 throw new ArgumentNullException("kern"); 910 }
911 } 911
912 kernel = kern; 912 private void CleanSolution(SolutionNode solution)
913 foreach (SolutionNode sol in kernel.Solutions) 913 {
914 { 914 kernel.Log.Write("Cleaning {0} solution and project files", VersionName, solution.Name);
915 CleanSolution(sol); 915
916 } 916 string slnFile = Helper.MakeFilePath(solution.FullPath, solution.Name, "sln");
917 kernel = null; 917 string suoFile = Helper.MakeFilePath(solution.FullPath, solution.Name, "suo");
918 } 918
919 919 Helper.DeleteIfExists(slnFile);
920 #endregion 920 Helper.DeleteIfExists(suoFile);
921 } 921
922} 922 foreach (ProjectNode project in solution.Projects)
923 {
924 CleanProject(project);
925 }
926
927 kernel.Log.Write("");
928 }
929
930 #endregion
931
932 #region ITarget Members
933
934 /// <summary>
935 /// Writes the specified kern.
936 /// </summary>
937 /// <param name="kern">The kern.</param>
938 public virtual void Write(Kernel kern)
939 {
940 if (kern == null)
941 {
942 throw new ArgumentNullException("kern");
943 }
944 kernel = kern;
945 foreach (SolutionNode sol in kernel.Solutions)
946 {
947 WriteSolution(sol, true);
948 }
949 kernel = null;
950 }
951
952 /// <summary>
953 /// Cleans the specified kern.
954 /// </summary>
955 /// <param name="kern">The kern.</param>
956 public virtual void Clean(Kernel kern)
957 {
958 if (kern == null)
959 {
960 throw new ArgumentNullException("kern");
961 }
962 kernel = kern;
963 foreach (SolutionNode sol in kernel.Solutions)
964 {
965 CleanSolution(sol);
966 }
967 kernel = null;
968 }
969
970 #endregion
971 }
972}