Skip to content

Commit 53c2732

Browse files
committed
Merge branch 'dev' of https://github.com/huangpf/azure-powershell into vmss2
2 parents d9f62c2 + bf8744b commit 53c2732

19 files changed

+1547
-0
lines changed
Lines changed: 120 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,120 @@
1+
// ----------------------------------------------------------------------------------
2+
//
3+
// Copyright Microsoft Corporation
4+
// Licensed under the Apache License, Version 2.0 (the "License");
5+
// you may not use this file except in compliance with the License.
6+
// You may obtain a copy of the License at
7+
// http://www.apache.org/licenses/LICENSE-2.0
8+
// Unless required by applicable law or agreed to in writing, software
9+
// distributed under the License is distributed on an "AS IS" BASIS,
10+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11+
// See the License for the specific language governing permissions and
12+
// limitations under the License.
13+
// ----------------------------------------------------------------------------------
14+
15+
using System;
16+
using System.Collections.Generic;
17+
using System.IO;
18+
using System.Linq;
19+
using System.Text;
20+
21+
namespace StaticAnalysis
22+
{
23+
/// <summary>
24+
/// Abstract class to implement the report logging structure
25+
/// </summary>
26+
public abstract class AnalysisLogger
27+
{
28+
string _baseDirectory;
29+
30+
/// <summary>
31+
/// Create an analysis logger that will write reports to the given directory
32+
/// </summary>
33+
/// <param name="baseDirectory"></param>
34+
public AnalysisLogger(string baseDirectory)
35+
{
36+
_baseDirectory = baseDirectory;
37+
}
38+
39+
IList<ReportLogger> _loggers = new List<ReportLogger>();
40+
protected virtual IList<ReportLogger> Loggers { get { return _loggers; } }
41+
42+
/// <summary>
43+
/// Write an error report.
44+
/// </summary>
45+
/// <param name="error">The message to write</param>
46+
public abstract void WriteError(string error);
47+
48+
public virtual void WriteError(string format, params object[] args)
49+
{
50+
WriteError(string.Format(format, args));
51+
}
52+
53+
/// <summary>
54+
/// Write an informational message.
55+
/// </summary>
56+
/// <param name="message">The message to write</param>
57+
public abstract void WriteMessage(string message);
58+
59+
public virtual void WriteMessage(string format, params object[] args)
60+
{
61+
WriteMessage(string.Format(format, args));
62+
}
63+
64+
/// <summary>
65+
/// Write a warning.
66+
/// </summary>
67+
/// <param name="message">The warning text</param>
68+
public abstract void WriteWarning(string message);
69+
70+
public virtual void WriteWarning(string format, params object[] args)
71+
{
72+
WriteWarning(string.Format(format, args));
73+
}
74+
75+
/// <summary>
76+
/// Write a report file to the given file, using the given file contents.
77+
/// </summary>
78+
/// <param name="name">The path to the file</param>
79+
/// <param name="contents">The contents of the report</param>
80+
public abstract void WriteReport(string name, string contents);
81+
82+
/// <summary>
83+
/// Create a logger for a particular report
84+
/// </summary>
85+
/// <typeparam name="T">The type of records written to the log</typeparam>
86+
/// <param name="fileName">The filename (without file path) where the report will be written</param>
87+
/// <returns>The given logger. Analyzer may write records to this logger and they will be written to
88+
/// the report file.</returns>
89+
public virtual ReportLogger<T> CreateLogger<T>(string fileName) where T : IReportRecord, new()
90+
{
91+
if (string.IsNullOrWhiteSpace(fileName))
92+
{
93+
throw new ArgumentNullException("fileName");
94+
}
95+
96+
var filePath = Path.Combine(_baseDirectory, fileName);
97+
var logger = new ReportLogger<T>(filePath, this);
98+
Loggers.Add(logger);
99+
return logger;
100+
}
101+
102+
/// <summary>
103+
/// Write out the report files for each of the added report loggers.
104+
/// </summary>
105+
public void WriteReports()
106+
{
107+
foreach (var logger in Loggers.Where(l => l.Records.Any()))
108+
{
109+
StringBuilder reportText = new StringBuilder();
110+
reportText.AppendLine(logger.Records.First().PrintHeaders());
111+
foreach (var reportRecord in logger.Records)
112+
{
113+
reportText.AppendLine(reportRecord.FormatRecord());
114+
}
115+
116+
WriteReport(logger.FileName, reportText.ToString());
117+
}
118+
}
119+
}
120+
}

tools/StaticAnalysis/ConsoleLogger.cs

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
// ----------------------------------------------------------------------------------
2+
//
3+
// Copyright Microsoft Corporation
4+
// Licensed under the Apache License, Version 2.0 (the "License");
5+
// you may not use this file except in compliance with the License.
6+
// You may obtain a copy of the License at
7+
// http://www.apache.org/licenses/LICENSE-2.0
8+
// Unless required by applicable law or agreed to in writing, software
9+
// distributed under the License is distributed on an "AS IS" BASIS,
10+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11+
// See the License for the specific language governing permissions and
12+
// limitations under the License.
13+
// ----------------------------------------------------------------------------------
14+
15+
using System;
16+
using System.IO;
17+
18+
namespace StaticAnalysis
19+
{
20+
/// <summary>
21+
/// Simple class for logging errors and warnings to the console and writing reports to the file system.
22+
/// </summary>
23+
public class ConsoleLogger : AnalysisLogger
24+
{
25+
26+
public ConsoleLogger(string baseDirectory)
27+
: base(baseDirectory)
28+
{
29+
}
30+
31+
public override void WriteError(string error)
32+
{
33+
Console.WriteLine("### ERROR {0}", error);
34+
}
35+
36+
public override void WriteMessage(string message)
37+
{
38+
Console.WriteLine(message);
39+
}
40+
41+
public override void WriteWarning(string message)
42+
{
43+
Console.WriteLine("Warning: {0}", message);
44+
}
45+
46+
public override void WriteReport(string name, string records)
47+
{
48+
File.WriteAllText(name, records);
49+
}
50+
}
51+
}

tools/StaticAnalysis/Decorator.cs

Lines changed: 88 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,88 @@
1+
// ----------------------------------------------------------------------------------
2+
//
3+
// Copyright Microsoft Corporation
4+
// Licensed under the Apache License, Version 2.0 (the "License");
5+
// you may not use this file except in compliance with the License.
6+
// You may obtain a copy of the License at
7+
// http://www.apache.org/licenses/LICENSE-2.0
8+
// Unless required by applicable law or agreed to in writing, software
9+
// distributed under the License is distributed on an "AS IS" BASIS,
10+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11+
// See the License for the specific language governing permissions and
12+
// limitations under the License.
13+
// ----------------------------------------------------------------------------------
14+
15+
using System;
16+
17+
namespace StaticAnalysis
18+
{
19+
/// <summary>
20+
/// Abstract class to implement the Decorator pattern
21+
/// </summary>
22+
/// <typeparam name="T"></typeparam>
23+
public class Decorator<T>
24+
{
25+
Action<T> _action;
26+
string _name;
27+
28+
protected Decorator(Action<T> action, string name)
29+
{
30+
_action = action;
31+
_name = name;
32+
Inner = null;
33+
}
34+
35+
public static Decorator<T> Create()
36+
{
37+
return new Decorator<T>(r => { }, "default");
38+
}
39+
40+
public void Apply(T record)
41+
{
42+
_action(record);
43+
if (Inner != null)
44+
{
45+
Inner.Apply(record);
46+
}
47+
}
48+
49+
public void AddDecorator(Action<T> action, string name)
50+
{
51+
if (action == null)
52+
{
53+
throw new ArgumentNullException("action");
54+
}
55+
56+
if (name == null)
57+
{
58+
throw new ArgumentNullException("name");
59+
}
60+
61+
if (Inner == null)
62+
{
63+
Inner = new Decorator<T>(action, name);
64+
}
65+
else
66+
{
67+
Inner.AddDecorator(action, name);
68+
}
69+
}
70+
71+
public void Remove(string name)
72+
{
73+
if (Inner != null)
74+
{
75+
if (string.Equals(Inner._name, name))
76+
{
77+
Inner = Inner.Inner;
78+
}
79+
else
80+
{
81+
Inner.Remove(name);
82+
}
83+
}
84+
}
85+
86+
protected Decorator<T> Inner { get; set; }
87+
}
88+
}
Lines changed: 101 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,101 @@
1+
// ----------------------------------------------------------------------------------
2+
//
3+
// Copyright Microsoft Corporation
4+
// Licensed under the Apache License, Version 2.0 (the "License");
5+
// you may not use this file except in compliance with the License.
6+
// You may obtain a copy of the License at
7+
// http://www.apache.org/licenses/LICENSE-2.0
8+
// Unless required by applicable law or agreed to in writing, software
9+
// distributed under the License is distributed on an "AS IS" BASIS,
10+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11+
// See the License for the specific language governing permissions and
12+
// limitations under the License.
13+
// ----------------------------------------------------------------------------------
14+
15+
using System;
16+
using System.Reflection;
17+
18+
namespace StaticAnalysis.DependencyAnalyzer
19+
{
20+
/// <summary>
21+
/// A class using .Net Remoting to load assemblies and retrieve information in a separate app domain
22+
/// </summary>
23+
public class AssemblyLoader : MarshalByRefObject
24+
{
25+
/// <summary>
26+
/// Load the assembly in the reflection context by name. Will succeed if the referenced assembly name can
27+
/// be found using default assembly loading rules (i.e. it is in the current directory or the GAC)
28+
/// </summary>
29+
/// <param name="assemblyName">The full name of the assembly</param>
30+
/// <returns>Information on the given assembly, if it was loaded successfully, or null if there is an
31+
/// assembly loading issue. </returns>
32+
public AssemblyMetadata GetReflectedAssemblyInfo(string assemblyName)
33+
{
34+
if (string.IsNullOrWhiteSpace(assemblyName))
35+
{
36+
throw new ArgumentException("assemblyName");
37+
}
38+
39+
AssemblyMetadata result = null;
40+
try
41+
{
42+
result = new AssemblyMetadata(Assembly.ReflectionOnlyLoad(assemblyName));
43+
}
44+
catch
45+
{
46+
}
47+
48+
return result;
49+
}
50+
51+
/// <summary>
52+
/// Load the assembly found at the given path in the reflection context and return assembly metadata
53+
/// </summary>
54+
/// <param name="assemblyPath">The full path to the assembly file.</param>
55+
/// <returns>Assembly metadata if the assembly is loaded successfully, or null if there are load errors.</returns>
56+
public AssemblyMetadata GetReflectedAssemblyFromFile(string assemblyPath)
57+
{
58+
if (string.IsNullOrWhiteSpace(assemblyPath))
59+
{
60+
throw new ArgumentException("assemblyPath");
61+
}
62+
63+
AssemblyMetadata result = null;
64+
try
65+
{
66+
return new AssemblyMetadata(Assembly.ReflectionOnlyLoadFrom(assemblyPath));
67+
}
68+
catch
69+
{
70+
}
71+
72+
return result;
73+
}
74+
75+
/// <summary>
76+
/// Create a new AppDomain and create a remote instance of AssemblyLoader we can use there
77+
/// </summary>
78+
/// <param name="directoryPath">directory containing assemblies</param>
79+
/// <param name="testDomain">A new AppDomain, where assemblies can be loaded</param>
80+
/// <returns>A proxy to the AssemblyLoader running in the newly created app domain</returns>
81+
public static AssemblyLoader Create(string directoryPath, out AppDomain testDomain)
82+
{
83+
if (string.IsNullOrWhiteSpace(directoryPath))
84+
{
85+
throw new ArgumentException("directoryPath");
86+
}
87+
88+
var setup = new AppDomainSetup();
89+
setup.ApplicationBase = directoryPath;
90+
setup.ApplicationName = "TestDomain";
91+
setup.ApplicationTrust = AppDomain.CurrentDomain.ApplicationTrust;
92+
setup.DisallowApplicationBaseProbing = false;
93+
setup.DisallowCodeDownload = false;
94+
setup.DisallowBindingRedirects = false;
95+
setup.DisallowPublisherPolicy = false;
96+
testDomain = AppDomain.CreateDomain("TestDomain", null, setup);
97+
return testDomain.CreateInstanceFromAndUnwrap(typeof(AssemblyLoader).Assembly.Location,
98+
typeof(AssemblyLoader).FullName) as AssemblyLoader;
99+
}
100+
}
101+
}

0 commit comments

Comments
 (0)