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