Skip to content

Commit d2eecfd

Browse files
russcamMpdreamz
authored andcommitted
Add buildalyzer components
- Cannot reference Buildalyzer nuget package directly as it is netstandard20. Include the necessary components within the DocGeneration project. - Similar to MsBuildWorkspace, Buildalyzer does not seem to add source documents within a project directory to the project. Add these manually for the Tests project. - Reference XML documentation files within the net46 build output directory - <Import> statements within csproj files look to be incorrectly rooted when building a workspace from the project.For instance: "<root>\src\build\Clients.Common.targets" was not found. Confirm that the path in the <Import> declaration is correct, and that the file exists on disk. The imported project "<root>\src\CodeGeneration\outputpath.props" was not found. Confirm that the path in the <Import> declaration is correct, and that the file exists on disk. To get documentation generation running again, for now, copy the files to the directories that they are expected in. Add additional string replacements for documentation Hide nested class Remove pragma directives from syntax text Revert reference paths to relative Experimenting with absolute paths vs. relative. Change makes no difference to project compilation so reverting this change Give doc generation more time
1 parent df6addb commit d2eecfd

27 files changed

+1481
-61
lines changed

build/scripts/Documentation.fsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ module Documentation =
2020
ExecProcess (fun p ->
2121
p.WorkingDirectory <- Paths.Source("CodeGeneration") @@ docGenerator.Name
2222
p.FileName <- generator
23-
) (TimeSpan.FromMinutes 1.) |> ignore
23+
) (TimeSpan.FromMinutes 2.) |> ignore
2424

2525
// TODO: hook documentation validation into the process
2626
let Validate() =

src/CodeGeneration/DocGenerator/AsciiDoc/GeneratedAsciidocVisitor.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -283,12 +283,12 @@ public override void Visit(AttributeEntry attributeEntry)
283283
switch (assemblyName.ToLowerInvariant())
284284
{
285285
case "elasticsearch.net":
286-
xmlDocsFile = Path.GetFullPath(Path.Combine(Program.BuildOutputPath, "Elasticsearch.Net.XML"));
286+
xmlDocsFile = Path.GetFullPath(Path.Combine(Program.BuildOutputPath, "Elasticsearch.Net", "net46", "Elasticsearch.Net.XML"));
287287
assembly = typeof(ElasticLowLevelClient).Assembly;
288288
assemblyNamespace = typeof(ElasticLowLevelClient).Namespace;
289289
break;
290290
default:
291-
xmlDocsFile = Path.GetFullPath(Path.Combine(Program.BuildOutputPath, "Nest.XML"));
291+
xmlDocsFile = Path.GetFullPath(Path.Combine(Program.BuildOutputPath, "Nest", "net46", "Nest.XML"));
292292
assembly = typeof(ElasticClient).Assembly;
293293
assemblyNamespace = typeof(ElasticClient).Namespace;
294294
break;
Lines changed: 163 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,163 @@
1+
#region License
2+
//MIT License
3+
//
4+
//Copyright (c) 2017 Dave Glick
5+
//
6+
//Permission is hereby granted, free of charge, to any person obtaining a copy
7+
//of this software and associated documentation files (the "Software"), to deal
8+
//in the Software without restriction, including without limitation the rights
9+
//to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10+
//copies of the Software, and to permit persons to whom the Software is
11+
//furnished to do so, subject to the following conditions:
12+
//
13+
//The above copyright notice and this permission notice shall be included in all
14+
//copies or substantial portions of the Software.
15+
//
16+
//THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17+
//IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18+
//FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19+
//AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20+
//LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21+
//OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22+
//SOFTWARE.
23+
#endregion
24+
25+
using System;
26+
using System.Collections.Generic;
27+
using System.IO;
28+
using System.Linq;
29+
using System.Xml.Linq;
30+
using DocGenerator.Buildalyzer.Logging;
31+
using Microsoft.Build.Construction;
32+
using Microsoft.Build.Framework;
33+
using Microsoft.Extensions.Logging;
34+
35+
namespace DocGenerator.Buildalyzer
36+
{
37+
public class AnalyzerManager
38+
{
39+
private readonly Dictionary<string, ProjectAnalyzer> _projects = new Dictionary<string, ProjectAnalyzer>();
40+
41+
public IReadOnlyDictionary<string, ProjectAnalyzer> Projects => _projects;
42+
43+
internal ILogger<ProjectAnalyzer> ProjectLogger { get; }
44+
45+
internal LoggerVerbosity LoggerVerbosity { get; }
46+
47+
public string SolutionDirectory { get; }
48+
49+
public AnalyzerManager(ILoggerFactory loggerFactory = null, LoggerVerbosity loggerVerbosity = LoggerVerbosity.Normal)
50+
: this(null, loggerFactory, loggerVerbosity)
51+
{
52+
}
53+
54+
public AnalyzerManager(TextWriter logWriter, LoggerVerbosity loggerVerbosity = LoggerVerbosity.Normal)
55+
: this(null, logWriter, loggerVerbosity)
56+
{
57+
}
58+
59+
public AnalyzerManager(string solutionFilePath, ILoggerFactory loggerFactory = null, LoggerVerbosity loggerVerbosity = LoggerVerbosity.Normal)
60+
{
61+
LoggerVerbosity = loggerVerbosity;
62+
ProjectLogger = loggerFactory?.CreateLogger<ProjectAnalyzer>();
63+
64+
if (solutionFilePath != null)
65+
{
66+
solutionFilePath = ValidatePath(solutionFilePath, true);
67+
SolutionDirectory = Path.GetDirectoryName(solutionFilePath);
68+
GetProjectsInSolution(solutionFilePath);
69+
}
70+
}
71+
72+
public AnalyzerManager(string solutionFilePath, TextWriter logWriter, LoggerVerbosity loggerVerbosity = LoggerVerbosity.Normal)
73+
{
74+
LoggerVerbosity = loggerVerbosity;
75+
if (logWriter != null)
76+
{
77+
LoggerFactory loggerFactory = new LoggerFactory();
78+
loggerFactory.AddProvider(new TextWriterLoggerProvider(logWriter));
79+
ProjectLogger = loggerFactory.CreateLogger<ProjectAnalyzer>();
80+
}
81+
82+
if (solutionFilePath != null)
83+
{
84+
solutionFilePath = ValidatePath(solutionFilePath, true);
85+
SolutionDirectory = Path.GetDirectoryName(solutionFilePath);
86+
GetProjectsInSolution(solutionFilePath);
87+
}
88+
}
89+
90+
private void GetProjectsInSolution(string solutionFilePath)
91+
{
92+
var supportedType = new[]
93+
{
94+
SolutionProjectType.KnownToBeMSBuildFormat,
95+
SolutionProjectType.WebProject
96+
};
97+
98+
SolutionFile solution = SolutionFile.Parse(solutionFilePath);
99+
foreach(ProjectInSolution project in solution.ProjectsInOrder)
100+
{
101+
if (!supportedType.Contains(project.ProjectType))
102+
continue;
103+
GetProject(project.AbsolutePath);
104+
}
105+
}
106+
107+
public ProjectAnalyzer GetProject(string projectFilePath)
108+
{
109+
if (projectFilePath == null)
110+
{
111+
throw new ArgumentNullException(nameof(projectFilePath));
112+
}
113+
114+
// Normalize as .sln uses backslash regardless of OS the sln is created on
115+
projectFilePath = projectFilePath.Replace('\\', Path.DirectorySeparatorChar);
116+
projectFilePath = ValidatePath(projectFilePath, true);
117+
if (_projects.TryGetValue(projectFilePath, out ProjectAnalyzer project))
118+
{
119+
return project;
120+
}
121+
project = new ProjectAnalyzer(this, projectFilePath);
122+
_projects.Add(projectFilePath, project);
123+
return project;
124+
}
125+
126+
public ProjectAnalyzer GetProject(string projectFilePath, XDocument projectDocument)
127+
{
128+
if (projectFilePath == null)
129+
{
130+
throw new ArgumentNullException(nameof(projectFilePath));
131+
}
132+
if (projectDocument == null)
133+
{
134+
throw new ArgumentNullException(nameof(projectDocument));
135+
}
136+
137+
// Normalize as .sln uses backslash regardless of OS the sln is created on
138+
projectFilePath = projectFilePath.Replace('\\', Path.DirectorySeparatorChar);
139+
projectFilePath = ValidatePath(projectFilePath, false);
140+
if (_projects.TryGetValue(projectFilePath, out ProjectAnalyzer project))
141+
{
142+
return project;
143+
}
144+
project = new ProjectAnalyzer(this, projectFilePath, projectDocument);
145+
_projects.Add(projectFilePath, project);
146+
return project;
147+
}
148+
149+
private static string ValidatePath(string path, bool checkExists)
150+
{
151+
if (path == null)
152+
{
153+
throw new ArgumentNullException(nameof(path));
154+
}
155+
path = Path.GetFullPath(path); // Normalize the path
156+
if (checkExists && !File.Exists(path))
157+
{
158+
throw new ArgumentException($"The path {path} could not be found.");
159+
}
160+
return path;
161+
}
162+
}
163+
}
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
#region License
2+
//MIT License
3+
//
4+
//Copyright (c) 2017 Dave Glick
5+
//
6+
//Permission is hereby granted, free of charge, to any person obtaining a copy
7+
//of this software and associated documentation files (the "Software"), to deal
8+
//in the Software without restriction, including without limitation the rights
9+
//to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10+
//copies of the Software, and to permit persons to whom the Software is
11+
//furnished to do so, subject to the following conditions:
12+
//
13+
//The above copyright notice and this permission notice shall be included in all
14+
//copies or substantial portions of the Software.
15+
//
16+
//THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17+
//IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18+
//FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19+
//AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20+
//LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21+
//OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22+
//SOFTWARE.
23+
#endregion
24+
25+
using Microsoft.CodeAnalysis;
26+
27+
namespace DocGenerator.Buildalyzer
28+
{
29+
public static class AnalyzerManagerExtensions
30+
{
31+
public static AdhocWorkspace GetWorkspace(this AnalyzerManager manager)
32+
{
33+
AdhocWorkspace workspace = new AdhocWorkspace();
34+
foreach (ProjectAnalyzer project in manager.Projects.Values)
35+
{
36+
project.AddToWorkspace(workspace);
37+
}
38+
return workspace;
39+
}
40+
}
41+
}
Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
#region License
2+
//MIT License
3+
//
4+
//Copyright (c) 2017 Dave Glick
5+
//
6+
//Permission is hereby granted, free of charge, to any person obtaining a copy
7+
//of this software and associated documentation files (the "Software"), to deal
8+
//in the Software without restriction, including without limitation the rights
9+
//to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10+
//copies of the Software, and to permit persons to whom the Software is
11+
//furnished to do so, subject to the following conditions:
12+
//
13+
//The above copyright notice and this permission notice shall be included in all
14+
//copies or substantial portions of the Software.
15+
//
16+
//THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17+
//IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18+
//FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19+
//AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20+
//LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21+
//OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22+
//SOFTWARE.
23+
#endregion
24+
25+
using System.Collections.Generic;
26+
27+
namespace DocGenerator.Buildalyzer.Environment
28+
{
29+
internal abstract class BuildEnvironment
30+
{
31+
private string _oldMsBuildExtensionsPath = null;
32+
private string _oldMsBuildSdksPath = null;
33+
34+
public abstract string GetToolsPath();
35+
36+
public virtual Dictionary<string, string> GetGlobalProperties(string solutionDir) =>
37+
new Dictionary<string, string>
38+
{
39+
{ MsBuildProperties.SolutionDir, solutionDir },
40+
{ MsBuildProperties.DesignTimeBuild, "true" },
41+
{ MsBuildProperties.BuildProjectReferences, "false" },
42+
{ MsBuildProperties.SkipCompilerExecution, "true" },
43+
{ MsBuildProperties.ProvideCommandLineArgs, "true" },
44+
// Workaround for a problem with resource files, see https://github.com/dotnet/sdk/issues/346#issuecomment-257654120
45+
{ MsBuildProperties.GenerateResourceMSBuildArchitecture, "CurrentArchitecture" }
46+
};
47+
48+
public virtual void SetEnvironmentVars(IReadOnlyDictionary<string, string> globalProperties)
49+
{
50+
if (globalProperties.TryGetValue(MsBuildProperties.MSBuildExtensionsPath, out var msBuildExtensionsPath))
51+
{
52+
_oldMsBuildExtensionsPath = System.Environment.GetEnvironmentVariable(MsBuildProperties.MSBuildExtensionsPath);
53+
System.Environment.SetEnvironmentVariable(MsBuildProperties.MSBuildExtensionsPath, msBuildExtensionsPath);
54+
}
55+
if (globalProperties.TryGetValue(MsBuildProperties.MSBuildSDKsPath, out var msBuildSDKsPath))
56+
{
57+
_oldMsBuildSdksPath = System.Environment.GetEnvironmentVariable(MsBuildProperties.MSBuildSDKsPath);
58+
System.Environment.SetEnvironmentVariable(MsBuildProperties.MSBuildSDKsPath, msBuildSDKsPath);
59+
}
60+
}
61+
62+
public virtual void UnsetEnvironmentVars()
63+
{
64+
if (_oldMsBuildExtensionsPath != null)
65+
{
66+
System.Environment.SetEnvironmentVariable(MsBuildProperties.MSBuildExtensionsPath, _oldMsBuildExtensionsPath);
67+
}
68+
if (_oldMsBuildSdksPath != null)
69+
{
70+
System.Environment.SetEnvironmentVariable(MsBuildProperties.MSBuildSDKsPath, _oldMsBuildSdksPath);
71+
}
72+
}
73+
}
74+
}
Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
#region License
2+
//MIT License
3+
//
4+
//Copyright (c) 2017 Dave Glick
5+
//
6+
//Permission is hereby granted, free of charge, to any person obtaining a copy
7+
//of this software and associated documentation files (the "Software"), to deal
8+
//in the Software without restriction, including without limitation the rights
9+
//to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10+
//copies of the Software, and to permit persons to whom the Software is
11+
//furnished to do so, subject to the following conditions:
12+
//
13+
//The above copyright notice and this permission notice shall be included in all
14+
//copies or substantial portions of the Software.
15+
//
16+
//THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17+
//IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18+
//FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19+
//AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20+
//LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21+
//OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22+
//SOFTWARE.
23+
#endregion
24+
25+
using System.Collections.Generic;
26+
using System.IO;
27+
28+
namespace DocGenerator.Buildalyzer.Environment
29+
{
30+
// Based on code from OmniSharp
31+
// https://github.com/OmniSharp/omnisharp-roslyn/blob/78ccc8b4376c73da282a600ac6fb10fce8620b52/src/OmniSharp.Abstractions/Services/DotNetCliService.cs
32+
internal class CoreEnvironment : BuildEnvironment
33+
{
34+
public string ToolsPath { get; }
35+
public string ExtensionsPath { get; }
36+
public string SDKsPath { get; }
37+
public string RoslynTargetsPath { get; }
38+
39+
public CoreEnvironment(string projectPath)
40+
{
41+
string dotnetPath = DotnetPathResolver.ResolvePath(projectPath);
42+
ToolsPath = dotnetPath;
43+
ExtensionsPath = dotnetPath;
44+
SDKsPath = Path.Combine(dotnetPath, "Sdks");
45+
RoslynTargetsPath = Path.Combine(dotnetPath, "Roslyn");
46+
}
47+
48+
public override string GetToolsPath() => ToolsPath;
49+
50+
public override Dictionary<string, string> GetGlobalProperties(string solutionDir)
51+
{
52+
Dictionary<string, string> globalProperties = base.GetGlobalProperties(solutionDir);
53+
globalProperties.Add(MsBuildProperties.MSBuildExtensionsPath, ExtensionsPath);
54+
globalProperties.Add(MsBuildProperties.MSBuildSDKsPath, SDKsPath);
55+
globalProperties.Add(MsBuildProperties.RoslynTargetsPath, RoslynTargetsPath);
56+
return globalProperties;
57+
}
58+
}
59+
}

0 commit comments

Comments
 (0)