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