Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/mono/mono-tools.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndrew Jorgensen <ajorgensen@novell.com>2008-01-31 20:04:34 +0300
committerAndrew Jorgensen <ajorgensen@novell.com>2008-01-31 20:04:34 +0300
commit9de757d227454a83fdfdb202d7ba79e0b442817c (patch)
treeac05dd06f003f5af5416bc093222cc8225d032d4 /gendarme/console
parent21f12adb44c6317dfa3172a77b497612084bbcb2 (diff)
Move gendarme into mono-tools
svn path=/trunk/mono-tools/; revision=94478
Diffstat (limited to 'gendarme/console')
-rw-r--r--gendarme/console/ChangeLog105
-rw-r--r--gendarme/console/ConsoleRunner.cs389
-rw-r--r--gendarme/console/HtmlResultWriter.cs90
-rw-r--r--gendarme/console/IResultWriter.cs47
-rw-r--r--gendarme/console/Makefile.am33
-rw-r--r--gendarme/console/TextResultWriter.cs98
-rw-r--r--gendarme/console/XmlResultWriter.cs132
-rw-r--r--gendarme/console/console.mdp31
-rwxr-xr-xgendarme/console/gendarme.csproj64
-rw-r--r--gendarme/console/gendarme.xsl166
10 files changed, 1155 insertions, 0 deletions
diff --git a/gendarme/console/ChangeLog b/gendarme/console/ChangeLog
new file mode 100644
index 00000000..a6557bd1
--- /dev/null
+++ b/gendarme/console/ChangeLog
@@ -0,0 +1,105 @@
+2008-01-12 Sebastien Pouliot <sebastien@ximian.com>
+
+ * ConsoleRunner.cs: Start using Gendarme.Console.Writers namespace.
+ Change a method to static.
+ * HtmlResultWriter.cs: Use 2.0 XslCompiledTransform (XslTransform
+ being obsolete). Move into Gendarme.Console.Writers namespace.
+ * IResultWriter.cs: Move into Gendarme.Console.Writers namespace.
+ * TextResultWriter.cs: Move into Gendarme.Console.Writers namespace.
+ * XmlResultWriter.cs: Move into Gendarme.Console.Writers namespace.
+ * console.mdp: MD removed the "./" before the filenames
+
+2007-11-30 Nestor Salceda <nestor.salceda@gmail.com>
+
+ * ConsoleRunner.cs: Extracted methods for avoid a long method violation
+ from Main.
+
+2007-11-29 Nestor Salceda <nestor.salceda@gmail.com>
+
+ * ConsoleRunner.cs: Don't ignore methods result (it fails a rule) in the
+ self-test.
+
+2007-11-29 Nestor Salceda <nestor.salceda@gmail.com>
+
+ * ConsoleRunner.cs: Added support for set values for some properties in
+ the configuration XML file.
+
+2007-11-21 Sebastien Pouliot <sebastien@ximian.com>
+
+ * ConsoleRunner.cs: Ensure patterns, like * and ?, works inside the
+ current directory. Return the full path in this case too.
+
+2007-10-08 Sebastien Pouliot <sebastien@ximian.com>
+
+ * ConsoleRunner.cs: Avoid WriteStaticFieldFromInstanceMethodRule
+ inside runner
+
+2007-10-07 Sebastien Pouliot <sebastien@ximian.com>
+
+ * console.mdp: Now built with 2.0 rutime.
+
+2006-10-15 Sebastien Pouliot <sebastien@ximian.com>
+
+ * gendarme.xsl: Create only one new browser-window per rule.
+
+2006-10-09 Sebastien Pouliot <sebastien@ximian.com>
+
+ * ConsoleRunner.cs: Provide more information with assemblies. Fix some
+ typos.
+ * gendarme.xsl: Add links to mono-project.com for rules. Fix defects
+ count on assemblies. Add defects count on rules. Ensure all defects
+ are reported (even if the location is unknown). Display more details
+ on where the defect are found (assembly, location).
+ * HtmlResultWriter.cs: Update signature for assemblies.
+ * IResultWriter.cs: Update signature for assemblies.
+ * Makefile.am: Rebuild gendarme.exe if the XSLT file changes.
+ * TextResultWriter.cs: Update signature for assemblies.
+ * XmlResultWriter.cs: Add fully-qualified assembly names when
+ outputing aasemblies. Add short-name and Uri when outputing rules.
+ Both enables more useful HTML reports.
+
+2006-09-28 Sebastien Pouliot <sebastien@ximian.com>
+
+ * Makefile.am: Adjust EXTRA_DIST to include project files in tarballs.
+
+2006-09-28 Christian Birkl <christian.birkl@gmail.com>
+
+ * gendarme.csproj: Included ChangeLog
+ * XmlResultWriter.cs, TextResultWriter.cs: Migrated untyped IList
+ messages collection to typed MessageCollection class.
+
+2006-09-17 Sebastien Pouliot <sebastien@ximian.com>
+
+ * console.mdp: Update MonoDevelop project file
+ * ConsoleRunner.cs: Add new options to the console runner.
+ * HtmlResultWriter.cs: New. Output HTML reports using the XML
+ output and the new XSL transform.
+ * IResultWriter.cs: New. Interface for all reporters. Original code
+ from Christian Birkl adapted/merged with existing code.
+ * Makefile.am: Add new files to the build.
+ * TextResultWriter.cs: New. Output text reports. Original code from
+ Christian Birkl adapted/merged with existing code.
+ * XmlResultWriter.cs: New. Output XML reports. Original code from
+ Christian Birkl adapted/merged with existing code.
+
+2006-09-17 Christian Birkl <christian.birkl@gmail.com>
+
+ * gendarme.xsl: New. XSLT file to transform XML output into HTML.
+
+2006-08-28 Sebastien Pouliot <sebastien@ximian.com>
+
+ * ConsoleRunner.cs: Fix exception when rules.xml contains XML
+ comments. Patch by Christian Birkl.
+
+2006-07-31 Sebastien Pouliot <sebastien@ximian.com>
+
+ * console.mdp: New. Project file for MonoDevelop.
+ * ConsoleRunner.cs: Adjust header display when Gendarme is compiled
+ from a MD project.
+
+2006-06-13 Sebastien Pouliot <sebastien@ximian.com>
+
+ * ConsoleRunner.cs: Read the copyright informations from the attribute
+ in AssemblyInfo.cs file. Fix NewLineLiteralRule in LoadConfiguration
+ method (self-test).
+ * Makefile.am: Added self-test to promote compliance ;-)
diff --git a/gendarme/console/ConsoleRunner.cs b/gendarme/console/ConsoleRunner.cs
new file mode 100644
index 00000000..3c9da508
--- /dev/null
+++ b/gendarme/console/ConsoleRunner.cs
@@ -0,0 +1,389 @@
+//
+// Gendarme Console Runner
+//
+// Authors:
+// Sebastien Pouliot <sebastien@ximian.com>
+//
+// Copyright (C) 2005-2008 Novell, Inc (http://www.novell.com)
+//
+// Permission is hereby granted, free of charge, to any person obtaining
+// a copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+
+using System;
+using System.Collections;
+using System.IO;
+using System.Reflection;
+using System.Text;
+using System.Xml;
+
+using Mono.Cecil;
+using Gendarme.Framework;
+using Gendarme.Console.Writers;
+
+class ConsoleRunner : Runner {
+
+ private const string defaultConfiguration = "rules.xml";
+ private const string defaultRuleSet = "default";
+
+ private string config;
+ private string set;
+ private Hashtable assemblies;
+ private string format;
+ private string output;
+
+ private static Assembly assembly;
+ private bool quiet;
+
+ static Assembly Assembly {
+ get {
+ if (assembly == null)
+ assembly = Assembly.GetExecutingAssembly ();
+ return assembly;
+ }
+ }
+
+ static string GetFullPath (string filename)
+ {
+ if (Path.GetDirectoryName (filename) != String.Empty)
+ return filename;
+ return Path.Combine (Path.GetDirectoryName (Assembly.Location), filename);
+ }
+
+ static string GetNext (string[] args, int index, string defaultValue)
+ {
+ if ((args == null) || (index < 0) || (index >= args.Length))
+ return defaultValue;
+ return args [index];
+ }
+
+ // name can be
+ // - a filename (a single assembly)
+ // - a mask (*, ?) for multiple assemblies
+ // - a special file (@) containing a list of assemblies
+ void AddFiles (string name)
+ {
+ if ((name == null) || (name.Length == 0))
+ return;
+
+ if (name.StartsWith ("@")) {
+ // note: recursive (can contains @, masks and filenames)
+ using (StreamReader sr = File.OpenText (name.Substring (1))) {
+ while (sr.Peek () >= 0) {
+ AddFiles (sr.ReadLine ());
+ }
+ }
+ } else if (name.IndexOfAny (new char[] { '*', '?' }) >= 0) {
+ string dirname = Path.GetDirectoryName (name);
+ if (dirname.Length == 0)
+ dirname = "."; // assume current directory
+ string [] files = Directory.GetFiles (dirname, Path.GetFileName (name));
+ foreach (string file in files) {
+ assemblies.Add (Path.GetFullPath (file), null);
+ }
+ } else {
+ assemblies.Add (Path.GetFullPath (name), null);
+ }
+ }
+
+ bool ParseOptions (string[] args)
+ {
+ // defaults
+ config = GetFullPath (defaultConfiguration);
+ set = defaultRuleSet;
+ assemblies = new Hashtable ();
+
+ // TODO - we probably want (i.e. later) the possibility to
+ // include/exclude certain rules from executing
+ for (int i=0; i < args.Length; i++) {
+ switch (args [i]) {
+ case "--config":
+ config = GetNext (args, ++i, defaultConfiguration);
+ break;
+ case "--set":
+ set = GetNext (args, ++i, defaultRuleSet);
+ break;
+ case "--debug":
+ debug = true;
+ break;
+ case "--quiet":
+ quiet = true;
+ break;
+ case "--help":
+ return false;
+ case "--log":
+ format = "text";
+ output = GetNext (args, ++i, String.Empty);
+ break;
+ case "--xml":
+ format = "xml";
+ output = GetNext (args, ++i, String.Empty);
+ break;
+ case "--html":
+ format = "html";
+ output = GetNext (args, ++i, String.Empty);
+ break;
+ default:
+ AddFiles (args[i]);
+ break;
+ }
+ }
+ return (assemblies.Count > 0);
+ }
+
+ bool LoadCustomParameters (XmlElement ruleset) {
+ foreach (XmlElement parameter in ruleset.SelectNodes ("parameter")) {
+ try {
+ if (!parameter.HasAttribute ("name"))
+ throw new XmlException ("The attribute name can't be found");
+ if (!parameter.HasAttribute ("value"))
+ throw new XmlException ("The attribute value can't be found");
+ if (!parameter.HasAttribute ("rule"))
+ throw new XmlException ("The attribute rule can't be found");
+
+ string name = GetAttribute (parameter, "name", String.Empty);
+ int value = 0;
+ try {
+ value = Int32.Parse (GetAttribute (parameter, "value", String.Empty));
+ }
+ catch (Exception exception) {
+ throw new XmlException ("The value for the value field should be an integer.", exception);
+ }
+ string ruleName = GetAttribute (parameter, "rule", String.Empty);
+
+ ApplyCustomParameterToRule (ruleName, name, value);
+ }
+ catch (Exception e) {
+ Console.WriteLine ("Error reading parameters{0}Details: {1}", Environment.NewLine, e);
+ return false;
+ }
+ }
+ return true;
+ }
+
+ static string GetAttribute (XmlElement xel, string name, string defaultValue)
+ {
+ XmlAttribute xa = xel.Attributes [name];
+ if (xa == null)
+ return defaultValue;
+ return xa.Value;
+ }
+
+ bool LoadConfiguration ()
+ {
+ XmlDocument doc = new XmlDocument ();
+ doc.Load (config);
+ if (doc.DocumentElement.Name != "gendarme")
+ return false;
+
+ bool result = false;
+ foreach (XmlElement ruleset in doc.DocumentElement.SelectNodes("ruleset")) {
+ if (ruleset.Attributes["name"].Value != set)
+ continue;
+ foreach (XmlElement assembly in ruleset.SelectNodes("rules")) {
+ string include = GetAttribute (assembly, "include", "*");
+ string exclude = GetAttribute (assembly, "exclude", String.Empty);
+ string from = GetFullPath (GetAttribute (assembly, "from", String.Empty));
+ try {
+ int n = LoadRulesFromAssembly (from, include, exclude);
+ result = (result || (n > 0));
+ }
+ catch (Exception e) {
+ Console.WriteLine ("Error reading rules{1}Details: {0}", e, Environment.NewLine);
+ return false;
+ }
+ }
+ if (!LoadCustomParameters (ruleset))
+ return false;
+ }
+ return result;
+ }
+
+ void ApplyCustomParameterToRule (string ruleName, string name, int value)
+ {
+ IRule rule = GetRule (ruleName);
+ if (rule == null)
+ throw new ArgumentException (String.Format ("The rule name {0} can't be found in the rules collection", ruleName), "rule");
+ PropertyInfo property = rule.GetType ().GetProperty (name);
+ if (property == null)
+ throw new ArgumentException (String.Format ("The property {0} can't be found in the rule {1}", name, ruleName), "name");
+ if (!property.CanWrite)
+ throw new ArgumentException (String.Format ("The property {0} can't be written in the rule {1}", name, ruleName), "name");
+ object result = property.GetSetMethod ().Invoke (rule, new object[] {value});
+ }
+
+ IRule GetRule (string name)
+ {
+ IRule result;
+ result = GetRuleFromSet (name, Rules.Assembly);
+ if (result == null) {
+ result = GetRuleFromSet (name, Rules.Module);
+ if (result == null) {
+ result = GetRuleFromSet (name, Rules.Type);
+ if (result == null) {
+ result = GetRuleFromSet (name, Rules.Method);
+ }
+ }
+ }
+ return result;
+ }
+
+ static IRule GetRuleFromSet (string name, RuleCollection rules)
+ {
+ foreach (IRule rule in rules) {
+ if (String.Compare (name, rule.GetType ().FullName) == 0)
+ return rule;
+ }
+ return null;
+ }
+
+ void Header ()
+ {
+ if (quiet)
+ return;
+
+ Assembly a = Assembly.GetExecutingAssembly();
+ Version v = a.GetName ().Version;
+ if (v.ToString () != "0.0.0.0") {
+ Console.WriteLine ("Gendarme v{0}", v);
+ object[] attr = a.GetCustomAttributes (typeof (AssemblyCopyrightAttribute), false);
+ if (attr.Length > 0)
+ Console.WriteLine (((AssemblyCopyrightAttribute) attr [0]).Copyright);
+ } else {
+ Console.WriteLine ("Gendarme - Development Snapshot");
+ }
+ Console.WriteLine ();
+ }
+
+ static void Help ()
+ {
+ Console.WriteLine ("Usage: gendarme [--config file] [--set ruleset] [--{log|xml|html} file] assembly");
+ Console.WriteLine ("Where");
+ Console.WriteLine (" --config file\t\tSpecify the configuration file. Default is 'rules.xml'.");
+ Console.WriteLine (" --set ruleset\t\tSpecify the set of rules to verify. Default is '*'.");
+ Console.WriteLine (" --log file\t\tSave the text output to the specified file.");
+ Console.WriteLine (" --xml file\t\tSave the output, as XML, to the specified file.");
+ Console.WriteLine (" --html file\t\tSave the output, as HTML, to the specified file.");
+ Console.WriteLine (" --quiet\t\tDisplay minimal output (results) from the runner.");
+ Console.WriteLine (" --debug\t\tEnable debugging output.");
+ Console.WriteLine (" assembly\t\tSpecify the assembly to verify.");
+ Console.WriteLine ();
+ }
+
+ void Write (string text)
+ {
+ if (!quiet)
+ Console.Write (text);
+ }
+
+ void WriteLine (string text)
+ {
+ if (!quiet)
+ Console.WriteLine (text);
+ }
+
+ void WriteLine (string text, params object[] args)
+ {
+ if (!quiet)
+ Console.WriteLine (text, args);
+ }
+
+ static void ProcessRules (ConsoleRunner runner)
+ {
+ runner.Header ();
+ string[] assemblies = new string [runner.assemblies.Count];
+ runner.assemblies.Keys.CopyTo (assemblies, 0);
+ DateTime total = DateTime.UtcNow;
+ foreach (string assembly in assemblies) {
+ DateTime start = DateTime.UtcNow;
+ runner.Write (assembly);
+ try {
+ AssemblyDefinition ad = AssemblyFactory.GetAssembly (assembly);
+ try {
+ runner.Process (ad);
+ runner.assemblies [assembly] = ad;
+ runner.WriteLine (" - completed ({0} seconds).", (DateTime.UtcNow - start).TotalSeconds);
+ }
+ catch (Exception e) {
+ runner.WriteLine (" - error executing rules{0}Details: {1}", Environment.NewLine, e);
+ }
+ }
+ catch (Exception e) {
+ runner.WriteLine (" - error processing{0}\tDetails: {1}", Environment.NewLine, e);
+ }
+ }
+ runner. WriteLine ("{0}{1} assemblies processed in {2} seconds.{0}", Environment.NewLine, runner.assemblies.Count,
+ (DateTime.UtcNow - total).TotalSeconds);
+ }
+
+ static void Report (ConsoleRunner runner)
+ {
+ IResultWriter writer;
+ switch (runner.format) {
+ case "xml":
+ writer = new XmlResultWriter (runner.output);
+ break;
+ case "html":
+ writer = new HtmlResultWriter (runner.output);
+ break;
+ default:
+ writer = new TextResultWriter (runner.output);
+ break;
+ }
+
+ writer.Start ();
+ writer.Write (runner.assemblies);
+ writer.Write (runner.Rules);
+ foreach (Violation v in runner.Violations) {
+ writer.Write (v);
+ }
+ writer.End ();
+ }
+
+ static int Main (string[] args)
+ {
+ ConsoleRunner runner = new ConsoleRunner ();
+
+ // runner options and configuration
+
+ try {
+ if (!runner.ParseOptions (args)) {
+ Help ();
+ return 1;
+ }
+ if (!runner.LoadConfiguration ()) {
+ Console.WriteLine ("No assembly file were specified.");
+ return 1;
+ }
+ }
+ catch (Exception e) {
+ Console.WriteLine (e);
+ return 1;
+ }
+
+ ProcessRules (runner);
+ Report (runner);
+
+ if (runner.Violations.Count == 0) {
+ runner.WriteLine ("No rule's violation were found.");
+ return 0;
+ }
+ return 1;
+ }
+}
diff --git a/gendarme/console/HtmlResultWriter.cs b/gendarme/console/HtmlResultWriter.cs
new file mode 100644
index 00000000..9b844971
--- /dev/null
+++ b/gendarme/console/HtmlResultWriter.cs
@@ -0,0 +1,90 @@
+//
+// HtmlResultWriter.cs
+//
+// Authors:
+// Sebastien Pouliot <sebastien@ximian.com>
+//
+// Copyright (C) 2006, 2008 Novell, Inc (http://www.novell.com)
+//
+// Permission is hereby granted, free of charge, to any person obtaining
+// a copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+
+using System;
+using System.Collections;
+using System.IO;
+using System.Reflection;
+using System.Xml;
+using System.Xml.Xsl;
+
+using Gendarme.Framework;
+
+namespace Gendarme.Console.Writers {
+
+ public class HtmlResultWriter : IResultWriter {
+
+ private XmlResultWriter writer;
+ private string temp_filename;
+ private string final_filename;
+
+ public HtmlResultWriter (string output)
+ {
+ final_filename = output;
+ temp_filename = Path.GetTempFileName ();
+ writer = new XmlResultWriter (temp_filename);
+ }
+
+ public void Start ()
+ {
+ writer.Start ();
+ }
+
+ public void End ()
+ {
+ try {
+ writer.End ();
+ // load XSL file from embedded resource
+ using (Stream s = Assembly.GetExecutingAssembly ().GetManifestResourceStream ("gendarme.xsl")) {
+ // process the XML result with the XSL file
+ XslCompiledTransform xslt = new XslCompiledTransform ();
+ xslt.Load (new XmlTextReader (s));
+ xslt.Transform (temp_filename, final_filename);
+ }
+ }
+ finally {
+ File.Delete (temp_filename);
+ }
+ }
+
+ public void Write (IDictionary assemblies)
+ {
+ writer.Write (assemblies);
+ }
+
+ public void Write (Rules rules)
+ {
+ writer.Write (rules);
+ }
+
+ public void Write (Violation v)
+ {
+ writer.Write (v);
+ }
+ }
+}
diff --git a/gendarme/console/IResultWriter.cs b/gendarme/console/IResultWriter.cs
new file mode 100644
index 00000000..281990de
--- /dev/null
+++ b/gendarme/console/IResultWriter.cs
@@ -0,0 +1,47 @@
+//
+// IResultWriter interface
+//
+// Authors:
+// Christian Birkl <christian.birkl@gmail.com>
+// Sebastien Pouliot <sebastien@ximian.com>
+//
+// Copyright (C) 2006 Christian Birkl
+// Copyright (C) 2006, 2008 Novell, Inc (http://www.novell.com)
+//
+// Permission is hereby granted, free of charge, to any person obtaining
+// a copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+
+using System;
+using System.Collections;
+
+using Gendarme.Framework;
+
+namespace Gendarme.Console.Writers {
+
+ public interface IResultWriter {
+
+ void Start ();
+ void End ();
+
+ void Write (IDictionary assemblies);
+ void Write (Rules rules);
+ void Write (Violation v);
+ }
+}
diff --git a/gendarme/console/Makefile.am b/gendarme/console/Makefile.am
new file mode 100644
index 00000000..eee7145d
--- /dev/null
+++ b/gendarme/console/Makefile.am
@@ -0,0 +1,33 @@
+gendarmedir=$(pkglibdir)
+gendarme_SCRIPTS = ../bin/gendarme.exe
+EXTRA_DIST = $(gendarme_sources) $(gendarme_sources_in) console.mdp gendarme.xsl gendarme.csproj
+CLEANFILES = $(gendarme_SCRIPTS) $(gendarme_SCRIPTS).mdb
+DISTCLEANFILES = Makefile.in
+
+gendarme_sources_in = ../AssemblyInfo.cs.in
+gendarme_generated_sources = $(gendarme_sources_in:.in=)
+gendarme_sources = ConsoleRunner.cs IResultWriter.cs TextResultWriter.cs XmlResultWriter.cs HtmlResultWriter.cs
+gendarme_resources = gendarme.xsl
+
+gendarme_build_sources = $(addprefix $(srcdir)/, $(gendarme_sources))
+gendarme_build_sources += $(gendarme_generated_sources)
+
+../bin/gendarme.exe: $(gendarme_build_sources) $(gendarme_resources)
+ $(MCS) -debug -pkg:mono-cecil -r:../bin/Gendarme.Framework.dll -r:System.Xml.dll -out:$@ $(gendarme_build_sources) \
+ -resource:gendarme.xsl
+
+self-test: ../bin/gendarme.exe
+ mono --debug ../bin/gendarme.exe ../bin/gendarme.exe
+
+# Install Unstable Mono Libraries (see configure.ac)
+
+install-data-hook:
+ for ASM in $(INSTALLED_ASSEMBLIES); do \
+ $(INSTALL) -c -m 0755 $$ASM $(DESTDIR)$(pkglibdir); \
+ done;
+
+uninstall-hook:
+ for ASM in $(INSTALLED_ASSEMBLIES); do \
+ rm -f $(DESTDIR)$(pkglibdir)/`basename $$ASM`; \
+ done;
+
diff --git a/gendarme/console/TextResultWriter.cs b/gendarme/console/TextResultWriter.cs
new file mode 100644
index 00000000..67dc8d55
--- /dev/null
+++ b/gendarme/console/TextResultWriter.cs
@@ -0,0 +1,98 @@
+//
+// TextResultWriter
+//
+// Authors:
+// Christian Birkl <christian.birkl@gmail.com>
+// Sebastien Pouliot <sebastien@ximian.com>
+//
+// Copyright (C) 2006 Christian Birkl
+// Copyright (C) 2006, 2008 Novell, Inc (http://www.novell.com)
+//
+// Permission is hereby granted, free of charge, to any person obtaining
+// a copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+
+using System;
+using System.Collections;
+using System.IO;
+
+using Gendarme.Framework;
+
+namespace Gendarme.Console.Writers {
+
+ public class TextResultWriter : IResultWriter {
+
+ private TextWriter writer;
+ private bool need_closing;
+ private int index;
+
+ public TextResultWriter (string output)
+ {
+ if ((output == null) || (output.Length == 0))
+ writer = System.Console.Out;
+ else {
+ writer = new StreamWriter (output);
+ need_closing = true;
+ }
+ }
+
+ public void Start ()
+ {
+ index = 0;
+ }
+
+ public void End ()
+ {
+ if (need_closing)
+ writer.Close ();
+ }
+
+ public void Write (IDictionary assemblies)
+ {
+ }
+
+ public void Write (Rules rules)
+ {
+ }
+
+ public void Write (Violation v)
+ {
+ RuleInformation ri = RuleInformationManager.GetRuleInformation (v.Rule);
+ writer.WriteLine ("{0}. {1}", ++index, ri.Name);
+ writer.WriteLine ();
+ writer.WriteLine ("Problem: {0}", String.Format (ri.Problem, v.Violator));
+ writer.WriteLine ();
+ if (v.Messages != null && v.Messages.Count > 0) {
+ writer.WriteLine ("Details:");
+ foreach (Message message in v.Messages) {
+ writer.WriteLine (" {0}", message);
+ }
+ writer.WriteLine ();
+ }
+ writer.WriteLine ("Solution: {0}", String.Format (ri.Solution, v.Violator));
+ writer.WriteLine ();
+ string url = ri.Uri;
+ if (url.Length > 0) {
+ writer.WriteLine ("More info available at: {0}", url);
+ writer.WriteLine ();
+ }
+ writer.WriteLine ();
+ }
+ }
+}
diff --git a/gendarme/console/XmlResultWriter.cs b/gendarme/console/XmlResultWriter.cs
new file mode 100644
index 00000000..be34fb25
--- /dev/null
+++ b/gendarme/console/XmlResultWriter.cs
@@ -0,0 +1,132 @@
+//
+// ResultWriter
+//
+// Authors:
+// Christian Birkl <christian.birkl@gmail.com>
+// Sebastien Pouliot <sebastien@ximian.com>
+//
+// Copyright (C) 2006 Christian Birkl
+// Copyright (C) 2006, 2008 Novell, Inc (http://www.novell.com)
+//
+// Permission is hereby granted, free of charge, to any person obtaining
+// a copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+
+using System;
+using System.Collections;
+using System.Text;
+using System.Xml;
+using System.Xml.Serialization;
+
+using Gendarme.Framework;
+using Mono.Cecil;
+
+namespace Gendarme.Console.Writers {
+
+ public class XmlResultWriter : IResultWriter {
+
+ private XmlTextWriter writer;
+
+ public XmlResultWriter (string output)
+ {
+ if ((output == null) || (output.Length == 0))
+ writer = new XmlTextWriter (System.Console.Out);
+ else
+ writer = new XmlTextWriter (output, Encoding.UTF8);
+ }
+
+ public void Start ()
+ {
+ writer.Formatting = Formatting.Indented;
+ writer.WriteProcessingInstruction ("xml", "version='1.0'");
+ writer.WriteStartElement ("gendarme-output");
+ writer.WriteAttributeString ("date", DateTime.UtcNow.ToString ());
+ }
+
+ public void End ()
+ {
+ writer.WriteEndElement ();
+ writer.Flush ();
+ writer.Close ();
+ writer = null;
+ }
+
+ public void Write (IDictionary assemblies)
+ {
+ foreach (DictionaryEntry de in assemblies) {
+ writer.WriteStartElement ("input");
+ AssemblyDefinition ad = (de.Value as AssemblyDefinition);
+ if (ad != null)
+ writer.WriteAttributeString ("Name", ad.Name.ToString ());
+ writer.WriteString ((string) de.Key);
+ writer.WriteEndElement ();
+ }
+ }
+
+ public void Write (Rules rules)
+ {
+ writer.WriteStartElement ("rules");
+ Rules ("Assembly", rules.Assembly);
+ Rules ("Module", rules.Module);
+ Rules ("Type", rules.Type);
+ Rules ("Method", rules.Method);
+ writer.WriteEndElement ();
+ }
+
+ private void Rules (string type, RuleCollection rules)
+ {
+ foreach (IRule rule in rules) {
+ RuleInformation info = RuleInformationManager.GetRuleInformation (rule);
+ writer.WriteStartElement ("rule");
+ writer.WriteAttributeString ("Name", info.Name);
+ writer.WriteAttributeString ("Type", type);
+ writer.WriteAttributeString ("Uri", info.Uri);
+ writer.WriteString (rule.GetType ().FullName);
+ writer.WriteEndElement ();
+ }
+ }
+
+ public void Write (Violation v)
+ {
+ RuleInformation ri = RuleInformationManager.GetRuleInformation (v.Rule);
+
+ writer.WriteStartElement ("violation");
+ writer.WriteAttributeString ("Assembly", v.Assembly.ToString ());
+ writer.WriteAttributeString ("Name", ri.Name);
+ writer.WriteAttributeString ("Uri", ri.Uri);
+ writer.WriteElementString ("problem", String.Format (ri.Problem, v.Violator));
+ writer.WriteElementString ("solution", String.Format (ri.Solution, v.Violator));
+
+ if ((v.Messages != null) && (v.Messages.Count > 0)) {
+ writer.WriteStartElement ("messages");
+ foreach (Message message in v.Messages) {
+ writer.WriteStartElement ("message");
+ if (message.Location != null)
+ writer.WriteAttributeString ("Location", message.Location.ToString ());
+ writer.WriteAttributeString ("Type", message.Type.ToString ());
+ writer.WriteString (message.Text);
+ writer.WriteEndElement ();
+ }
+ writer.WriteEndElement ();
+ }
+
+ writer.WriteEndElement ();
+ }
+ }
+}
diff --git a/gendarme/console/console.mdp b/gendarme/console/console.mdp
new file mode 100644
index 00000000..bfe58bdb
--- /dev/null
+++ b/gendarme/console/console.mdp
@@ -0,0 +1,31 @@
+<Project name="console" fileversion="2.0" language="C#" clr-version="Net_2_0" ctype="DotNetProject">
+ <Configurations active="Debug">
+ <Configuration name="Debug" ctype="DotNetProjectConfiguration">
+ <Output directory="../bin" assembly="gendarme" />
+ <Build debugmode="True" target="Exe" />
+ <Execution runwithwarnings="True" externalconsole="True" consolepause="True" runtime="MsNet" clr-version="Net_2_0" />
+ <CodeGeneration compiler="Csc" warninglevel="4" optimize="True" unsafecodeallowed="False" generateoverflowchecks="True" mainclass="" generatexmldocumentation="False" ctype="CSharpCompilerParameters" />
+ </Configuration>
+ <Configuration name="Release" ctype="DotNetProjectConfiguration">
+ <Output directory="../bin/Release" assembly="gendarme" />
+ <Build debugmode="False" target="Exe" />
+ <Execution runwithwarnings="True" consolepause="True" runtime="MsNet" clr-version="Net_2_0" />
+ <CodeGeneration compiler="Csc" warninglevel="4" optimize="True" unsafecodeallowed="False" generateoverflowchecks="True" mainclass="" generatexmldocumentation="False" ctype="CSharpCompilerParameters" />
+ </Configuration>
+ </Configurations>
+ <Contents>
+ <File name="ConsoleRunner.cs" subtype="Code" buildaction="Compile" />
+ <File name="IResultWriter.cs" subtype="Code" buildaction="Compile" />
+ <File name="TextResultWriter.cs" subtype="Code" buildaction="Compile" />
+ <File name="XmlResultWriter.cs" subtype="Code" buildaction="Compile" />
+ <File name="gendarme.xsl" subtype="Code" buildaction="EmbedAsResource" />
+ <File name="HtmlResultWriter.cs" subtype="Code" buildaction="Compile" />
+ </Contents>
+ <References>
+ <ProjectReference type="Project" localcopy="True" refto="framework" />
+ <ProjectReference type="Assembly" localcopy="True" refto="../../lib/Mono.Cecil.dll" />
+ <ProjectReference type="Gac" localcopy="True" refto="System, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" />
+ <ProjectReference type="Gac" localcopy="True" refto="System.Xml, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" />
+ </References>
+ <DeployTargets />
+</Project> \ No newline at end of file
diff --git a/gendarme/console/gendarme.csproj b/gendarme/console/gendarme.csproj
new file mode 100755
index 00000000..6fff5844
--- /dev/null
+++ b/gendarme/console/gendarme.csproj
@@ -0,0 +1,64 @@
+<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <PropertyGroup>
+ <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+ <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+ <ProductVersion>8.0.50727</ProductVersion>
+ <SchemaVersion>2.0</SchemaVersion>
+ <ProjectGuid>{E95A3AB9-A303-4859-8BCA-458C79496548}</ProjectGuid>
+ <OutputType>Exe</OutputType>
+ <AppDesignerFolder>Properties</AppDesignerFolder>
+ <RootNamespace>gendarme</RootNamespace>
+ <AssemblyName>gendarme</AssemblyName>
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
+ <DebugSymbols>true</DebugSymbols>
+ <DebugType>full</DebugType>
+ <Optimize>false</Optimize>
+ <OutputPath>bin\Debug\</OutputPath>
+ <DefineConstants>DEBUG;TRACE</DefineConstants>
+ <ErrorReport>prompt</ErrorReport>
+ <WarningLevel>4</WarningLevel>
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
+ <DebugType>pdbonly</DebugType>
+ <Optimize>true</Optimize>
+ <OutputPath>bin\Release\</OutputPath>
+ <DefineConstants>TRACE</DefineConstants>
+ <ErrorReport>prompt</ErrorReport>
+ <WarningLevel>4</WarningLevel>
+ </PropertyGroup>
+ <ItemGroup>
+ <Reference Include="System" />
+ <Reference Include="System.Xml" />
+ </ItemGroup>
+ <ItemGroup>
+ </ItemGroup>
+ <ItemGroup>
+ <Compile Include="ConsoleRunner.cs" />
+ <Compile Include="HtmlResultWriter.cs" />
+ <Compile Include="IResultWriter.cs" />
+ <Compile Include="TextResultWriter.cs" />
+ <Compile Include="XmlResultWriter.cs" />
+ </ItemGroup>
+ <ItemGroup>
+ <ProjectReference Include="..\..\lib\Mono.Cecil.csproj">
+ <Project>{D8F63DFF-5230-43E4-9AB2-DA6E721A1FAE}</Project>
+ <Name>Mono.Cecil</Name>
+ </ProjectReference>
+ <ProjectReference Include="..\framework\Gendarme.Framework.csproj">
+ <Project>{CD6818D5-B398-486C-B180-92A07B143AFD}</Project>
+ <Name>Gendarme.Framework</Name>
+ </ProjectReference>
+ </ItemGroup>
+ <ItemGroup>
+ <None Include="ChangeLog" />
+ </ItemGroup>
+ <Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
+ <!-- To modify your build process, add your task inside one of the targets below and uncomment it.
+ Other similar extension points exist, see Microsoft.Common.targets.
+ <Target Name="BeforeBuild">
+ </Target>
+ <Target Name="AfterBuild">
+ </Target>
+ -->
+</Project> \ No newline at end of file
diff --git a/gendarme/console/gendarme.xsl b/gendarme/console/gendarme.xsl
new file mode 100644
index 00000000..e13af536
--- /dev/null
+++ b/gendarme/console/gendarme.xsl
@@ -0,0 +1,166 @@
+<?xml version="1.0" encoding="iso-8859-1" ?>
+<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
+ <xsl:output method="html" encoding="iso-8859-1" />
+ <xsl:template name="print-defect-rules">
+ <xsl:param name="name" />
+ : <xsl:value-of select="count(//violation[@Name = $name])" /> defects
+ </xsl:template>
+ <xsl:template name="print-rules">
+ <xsl:param name="type" />
+ <p>
+ <b><xsl:value-of select="$type" /></b>:
+ <xsl:choose>
+ <xsl:when test="count(rules/rule[@Type = $type]) = 0">
+ <ul>
+ <li>None</li>
+ </ul>
+ </xsl:when>
+ <xsl:otherwise>
+ <ul>
+ <xsl:for-each select="rules/rule[@Type = $type]">
+ <li>
+ <a href="{@Uri}" target="{@Name}"><xsl:value-of select="text()" /></a>
+ <xsl:call-template name="print-defect-rules">
+ <xsl:with-param name="name">
+ <xsl:value-of select="@Name" />
+ </xsl:with-param>
+ </xsl:call-template>
+ </li>
+ </xsl:for-each>
+ </ul>
+ </xsl:otherwise>
+ </xsl:choose>
+ </p>
+ </xsl:template>
+ <xsl:template match="/">
+ <xsl:for-each select="gendarme-output">
+ <html>
+ <head>
+ <title>Gendarme Report</title>
+ </head>
+ <style type="text/css">
+ h1, h2, h3 {
+ font-family: Verdana;
+ color: #68892F;
+ }
+ h2 {
+ font-size: 14pt;
+ }
+
+ p, li, b {
+ font-family: Verdana;
+ font-size: 11pt;
+ }
+ p.where, p.problem, p.found, p.solution {
+ background-color: #F6F6F6;
+ border: 1px solid #DDDDDD;
+ padding: 10px;
+ }
+ span.found {
+ padding: 10px;
+ }
+ div.toc {
+ background-color: #F6F6F6;
+ border: 1px solid #DDDDDD;
+ padding: 10px;
+ float: right;
+ width: 300px;
+ }
+ a:link, a:active, a:hover, a:visited {
+ color: #9F75AD;
+ font-weight: bold;
+ text-decoration: none;
+ }
+ </style>
+ <body>
+
+ <h1>Gendarme Report</h1>
+ <p>Produced on <xsl:value-of select="@date" /> UTC.</p>
+
+ <div class="toc">
+ <div align="center">
+ <b style="font-size: 10pt;">Table of contents</b>
+ </div>
+ <p style="font-size: 10pt;">
+ <a href="#s1">1&#160;&#160;Summary</a><br />
+ <a href="#s1_1">&#160;&#160;1.1&#160;&#160;List of assemblies searched</a><br />
+ <a href="#s1_2">&#160;&#160;1.2&#160;&#160;List of rules used</a><br />
+ <a href="#s2">2&#160;&#160;Reported defects</a><br />
+ </p>
+ </div>
+ <h1><a name="s1">Summary</a></h1>
+
+ <p>
+ <h2>List of assemblies analyzed</h2>
+ <ul>
+ <xsl:for-each select="input">
+ <xsl:variable name="assembly"><xsl:value-of select="@Name" /></xsl:variable>
+
+ <li><xsl:value-of select="text()" />: <xsl:value-of select="count(//violation[@Assembly = $assembly])" /> defects</li>
+ </xsl:for-each>
+ </ul>
+ </p>
+
+ <p>
+ <h2>List of rules used</h2>
+
+ <xsl:call-template name="print-rules">
+ <xsl:with-param name="type">Assembly</xsl:with-param>
+ </xsl:call-template>
+
+ <xsl:call-template name="print-rules">
+ <xsl:with-param name="type">Module</xsl:with-param>
+ </xsl:call-template>
+
+ <xsl:call-template name="print-rules">
+ <xsl:with-param name="type">Type</xsl:with-param>
+ </xsl:call-template>
+
+ <xsl:call-template name="print-rules">
+ <xsl:with-param name="type">Method</xsl:with-param>
+ </xsl:call-template>
+ </p>
+
+ <h1><a name="s2">Reported Defects</a></h1>
+
+ <p>
+ <xsl:for-each select="violation">
+ <h3><xsl:value-of select="position()" />&#160;
+ <a href="{@Uri}" target="{@Name}">
+ <xsl:value-of select="@Name" />
+ </a>
+ </h3>
+
+ <b>Problem:</b>
+ <p class="problem">
+ <xsl:value-of select="problem" />
+ </p>
+
+ <b>Found in:</b>
+ <p class="found">
+ Assembly Qualified Name: <i><xsl:value-of select="@Assembly" /></i><br/>
+ <xsl:if test="count(messages/message) != 0">
+ <xsl:for-each select="messages/message">
+ <br/>
+<!-- FIXME: use different color/style for warnings versus errors -->
+ <b>Location:</b>&#160;<xsl:value-of select="@Location" />
+ <br/>
+ <span class="found">
+ <xsl:value-of select="../message" />
+ </span>
+ <br/>
+ </xsl:for-each>
+ </xsl:if>
+ </p>
+
+ <b>Solution:</b>
+ <p class="solution">
+ <xsl:value-of select="solution" />
+ </p>
+ </xsl:for-each>
+ </p>
+ </body>
+ </html>
+ </xsl:for-each>
+ </xsl:template>
+</xsl:stylesheet>