diff options
author | Andrew Jorgensen <ajorgensen@novell.com> | 2008-01-31 20:04:34 +0300 |
---|---|---|
committer | Andrew Jorgensen <ajorgensen@novell.com> | 2008-01-31 20:04:34 +0300 |
commit | 9de757d227454a83fdfdb202d7ba79e0b442817c (patch) | |
tree | ac05dd06f003f5af5416bc093222cc8225d032d4 /gendarme/console | |
parent | 21f12adb44c6317dfa3172a77b497612084bbcb2 (diff) |
Move gendarme into mono-tools
svn path=/trunk/mono-tools/; revision=94478
Diffstat (limited to 'gendarme/console')
-rw-r--r-- | gendarme/console/ChangeLog | 105 | ||||
-rw-r--r-- | gendarme/console/ConsoleRunner.cs | 389 | ||||
-rw-r--r-- | gendarme/console/HtmlResultWriter.cs | 90 | ||||
-rw-r--r-- | gendarme/console/IResultWriter.cs | 47 | ||||
-rw-r--r-- | gendarme/console/Makefile.am | 33 | ||||
-rw-r--r-- | gendarme/console/TextResultWriter.cs | 98 | ||||
-rw-r--r-- | gendarme/console/XmlResultWriter.cs | 132 | ||||
-rw-r--r-- | gendarme/console/console.mdp | 31 | ||||
-rwxr-xr-x | gendarme/console/gendarme.csproj | 64 | ||||
-rw-r--r-- | gendarme/console/gendarme.xsl | 166 |
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  Summary</a><br />
+ <a href="#s1_1">  1.1  List of assemblies searched</a><br />
+ <a href="#s1_2">  1.2  List of rules used</a><br />
+ <a href="#s2">2  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()" />  + <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> <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> |