2 people like it.

Migrate from Settings.StyleCop to .ruleset

https://github.com/DotNetAnalyzers/StyleCopAnalyzers/issues/1099

 1: 
 2: 
 3: 
 4: 
 5: 
 6: 
 7: 
 8: 
 9: 
10: 
11: 
12: 
13: 
14: 
15: 
16: 
17: 
18: 
19: 
20: 
21: 
22: 
23: 
24: 
25: 
26: 
27: 
28: 
29: 
30: 
31: 
32: 
33: 
34: 
35: 
36: 
37: 
38: 
39: 
40: 
41: 
42: 
43: 
44: 
45: 
46: 
47: 
48: 
49: 
50: 
51: 
52: 
53: 
54: 
55: 
56: 
57: 
58: 
59: 
60: 
61: 
62: 
63: 
64: 
65: 
66: 
67: 
68: 
69: 
70: 
71: 
72: 
73: 
74: 
75: 
76: 
77: 
78: 
79: 
80: 
81: 
82: 
83: 
84: 
85: 
#r "System.Xml.Linq.dll"

open System.IO
open System.Xml.Linq
open System.Text.RegularExpressions

//Script will read all old rules entries from Settings.StyleCop file
//they will be merged with existing rules in FxCop.ruleset (generated by Visual Studio)
let oldRulesFile = "Settings.StyleCop"
let newRulesFile = "FxCop.ruleset"
//https://github.com/StyleCop/StyleCop/raw/master/Project/Docs/Rules/Index.hhk
//used for Id <-> Name maping
let allRulesIndexFile = "Index.hhk"

type RuleAction = Warning | Error | Hidden | Info | None
                  override this.ToString() = sprintf "%A" this

type Rule = { Id : string; Name: string; Action: RuleAction }
            override this.ToString() = sprintf "%s: %s" this.Id this.Name

let defaultAction = None

let stringToRule str = 
  match str with
  | "Warning" -> Warning
  | "Error" -> Error
  | "Hidden" -> Hidden
  | "Info" -> Info
  | _ -> None

let xelement name children =
    XElement(XName.Get name, (Seq.cast children:XObject seq))

let xattribute name value =
    XAttribute(XName.Get name, value) :> XObject

let allRules = 
  File.ReadAllText allRulesIndexFile
  |> fun input -> Regex.Matches(input, """(\w\w\d+): (\w+)""")
  |> Seq.cast<Match>
  |> Seq.map (fun x -> { Id = x.Groups.[1].Value; Name = x.Groups.[2].Value; Action = defaultAction })
  
let allRulesMap = Map.ofSeq <| Seq.map (fun rule -> (rule.Name, rule)) allRules

let oldRules =
  File.ReadAllText oldRulesFile
  |> XDocument.Parse
  |> fun xml -> xml.Descendants(XName.Get("Rule"))
  |> Seq.map (fun el -> { Id = null; Name = el.Attribute(XName.Get("Name")).Value; Action = defaultAction })

let document = XDocument.Parse <| File.ReadAllText newRulesFile
let root = document.Root;
let styleCopNode = 
  root.Descendants(XName.Get "Rules")
  |> Seq.filter (fun x -> x.Attribute(XName.Get "AnalyzerId").Value = "StyleCop.Analyzers")
  |> Seq.cast<XElement>
  |> Seq.tryHead
let mutable existingRules = 
  match styleCopNode with
    | Some node -> 
        node.Remove() |> ignore //remove to replace later with the new one
        node.Descendants(XName.Get "Rule")
        |> Seq.map (fun x -> { Id = x.Attribute(XName.Get "Id").Value; Action = stringToRule (x.Attribute(XName.Get "Action").Value); Name = null })
    | _ -> Seq.empty

let mutable matched = List.Empty
let mutable notMatched = List.Empty
for rule in oldRules do
  match allRulesMap |> Map.tryFind rule.Name with
    | Some x -> matched <- List.append matched [{x with Action = rule.Action}]
    | _ -> notMatched <- List.append notMatched [rule]
  |> ignore

existingRules
  |> Seq.filter (fun rule -> Option.isNone <| List.tryFind (fun x -> x.Id = rule.Id) matched)
  |> Seq.append matched
  |> Seq.map (fun rule -> xelement "Rule" [ xattribute "Id" rule.Id; xattribute "Action" (string rule.Action) ])
  |> Seq.cast<XObject>
  |> Seq.append [ xattribute "AnalyzerId" "StyleCop.Analyzers"; xattribute "RuleNamespace" "StyleCop.Analyzers" ]
  |> xelement "Rules"
  |> root.Add

document.Save(newRulesFile)

printfn "Not matched: %d" notMatched.Length
namespace System
namespace System.IO
namespace System.Xml
namespace System.Xml.Linq
namespace System.Text
namespace System.Text.RegularExpressions
val oldRulesFile : string

Full name: Script.oldRulesFile
val newRulesFile : string

Full name: Script.newRulesFile
val allRulesIndexFile : string

Full name: Script.allRulesIndexFile
type RuleAction =
  | Warning
  | Error
  | Hidden
  | Info
  | None
  override ToString : unit -> string

Full name: Script.RuleAction
union case RuleAction.Warning: RuleAction
union case RuleAction.Error: RuleAction
union case RuleAction.Hidden: RuleAction
union case RuleAction.Info: RuleAction
union case RuleAction.None: RuleAction
val this : RuleAction
override RuleAction.ToString : unit -> string

Full name: Script.RuleAction.ToString
val sprintf : format:Printf.StringFormat<'T> -> 'T

Full name: Microsoft.FSharp.Core.ExtraTopLevelOperators.sprintf
type Rule =
  {Id: string;
   Name: string;
   Action: RuleAction;}
  override ToString : unit -> string

Full name: Script.Rule
Rule.Id: string
Multiple items
val string : value:'T -> string

Full name: Microsoft.FSharp.Core.Operators.string

--------------------
type string = System.String

Full name: Microsoft.FSharp.Core.string
Rule.Name: string
Rule.Action: RuleAction
val this : Rule
override Rule.ToString : unit -> string

Full name: Script.Rule.ToString
val defaultAction : RuleAction

Full name: Script.defaultAction
val stringToRule : str:string -> RuleAction

Full name: Script.stringToRule
val str : string
val xelement : name:string -> children:System.Collections.IEnumerable -> XElement

Full name: Script.xelement
val name : string
val children : System.Collections.IEnumerable
Multiple items
type XElement =
  inherit XContainer
  new : name:XName -> XElement + 4 overloads
  member AncestorsAndSelf : unit -> IEnumerable<XElement> + 1 overload
  member Attribute : name:XName -> XAttribute
  member Attributes : unit -> IEnumerable<XAttribute> + 1 overload
  member DescendantNodesAndSelf : unit -> IEnumerable<XNode>
  member DescendantsAndSelf : unit -> IEnumerable<XElement> + 1 overload
  member FirstAttribute : XAttribute
  member GetDefaultNamespace : unit -> XNamespace
  member GetNamespaceOfPrefix : prefix:string -> XNamespace
  member GetPrefixOfNamespace : ns:XNamespace -> string
  ...

Full name: System.Xml.Linq.XElement

--------------------
XElement(name: XName) : unit
XElement(other: XElement) : unit
XElement(other: XStreamingElement) : unit
XElement(name: XName, content: obj) : unit
XElement(name: XName, [<System.ParamArray>] content: obj []) : unit
type XName =
  member Equals : obj:obj -> bool
  member GetHashCode : unit -> int
  member LocalName : string
  member Namespace : XNamespace
  member NamespaceName : string
  member ToString : unit -> string
  static member Get : expandedName:string -> XName + 1 overload

Full name: System.Xml.Linq.XName
XName.Get(expandedName: string) : XName
XName.Get(localName: string, namespaceName: string) : XName
module Seq

from Microsoft.FSharp.Collections
val cast : source:System.Collections.IEnumerable -> seq<'T>

Full name: Microsoft.FSharp.Collections.Seq.cast
type XObject =
  member AddAnnotation : annotation:obj -> unit
  member Annotation<'T> : unit -> 'T + 1 overload
  member Annotations<'T> : unit -> IEnumerable<'T> + 1 overload
  member BaseUri : string
  member Document : XDocument
  member NodeType : XmlNodeType
  member Parent : XElement
  member RemoveAnnotations<'T> : unit -> unit + 1 overload
  event Changed : EventHandler<XObjectChangeEventArgs>
  event Changing : EventHandler<XObjectChangeEventArgs>

Full name: System.Xml.Linq.XObject
Multiple items
val seq : sequence:seq<'T> -> seq<'T>

Full name: Microsoft.FSharp.Core.Operators.seq

--------------------
type seq<'T> = System.Collections.Generic.IEnumerable<'T>

Full name: Microsoft.FSharp.Collections.seq<_>
val xattribute : name:string -> value:'a -> XObject

Full name: Script.xattribute
val value : 'a
Multiple items
type XAttribute =
  inherit XObject
  new : other:XAttribute -> XAttribute + 1 overload
  member IsNamespaceDeclaration : bool
  member Name : XName
  member NextAttribute : XAttribute
  member NodeType : XmlNodeType
  member PreviousAttribute : XAttribute
  member Remove : unit -> unit
  member SetValue : value:obj -> unit
  member ToString : unit -> string
  member Value : string with get, set
  ...

Full name: System.Xml.Linq.XAttribute

--------------------
XAttribute(other: XAttribute) : unit
XAttribute(name: XName, value: obj) : unit
val allRules : seq<Rule>

Full name: Script.allRules
type File =
  static member AppendAllLines : path:string * contents:IEnumerable<string> -> unit + 1 overload
  static member AppendAllText : path:string * contents:string -> unit + 1 overload
  static member AppendText : path:string -> StreamWriter
  static member Copy : sourceFileName:string * destFileName:string -> unit + 1 overload
  static member Create : path:string -> FileStream + 3 overloads
  static member CreateText : path:string -> StreamWriter
  static member Decrypt : path:string -> unit
  static member Delete : path:string -> unit
  static member Encrypt : path:string -> unit
  static member Exists : path:string -> bool
  ...

Full name: System.IO.File
File.ReadAllText(path: string) : string
File.ReadAllText(path: string, encoding: System.Text.Encoding) : string
val input : string
Multiple items
type Regex =
  new : pattern:string -> Regex + 1 overload
  member GetGroupNames : unit -> string[]
  member GetGroupNumbers : unit -> int[]
  member GroupNameFromNumber : i:int -> string
  member GroupNumberFromName : name:string -> int
  member IsMatch : input:string -> bool + 1 overload
  member Match : input:string -> Match + 2 overloads
  member Matches : input:string -> MatchCollection + 1 overload
  member Options : RegexOptions
  member Replace : input:string * replacement:string -> string + 5 overloads
  ...

Full name: System.Text.RegularExpressions.Regex

--------------------
Regex(pattern: string) : unit
Regex(pattern: string, options: RegexOptions) : unit
Regex.Matches(input: string, pattern: string) : MatchCollection
Regex.Matches(input: string, pattern: string, options: RegexOptions) : MatchCollection
type Match =
  inherit Group
  member Groups : GroupCollection
  member NextMatch : unit -> Match
  member Result : replacement:string -> string
  static member Empty : Match
  static member Synchronized : inner:Match -> Match

Full name: System.Text.RegularExpressions.Match
val map : mapping:('T -> 'U) -> source:seq<'T> -> seq<'U>

Full name: Microsoft.FSharp.Collections.Seq.map
val x : Match
property Match.Groups: GroupCollection
val allRulesMap : Map<string,Rule>

Full name: Script.allRulesMap
Multiple items
module Map

from Microsoft.FSharp.Collections

--------------------
type Map<'Key,'Value (requires comparison)> =
  interface IEnumerable
  interface IComparable
  interface IEnumerable<KeyValuePair<'Key,'Value>>
  interface ICollection<KeyValuePair<'Key,'Value>>
  interface IDictionary<'Key,'Value>
  new : elements:seq<'Key * 'Value> -> Map<'Key,'Value>
  member Add : key:'Key * value:'Value -> Map<'Key,'Value>
  member ContainsKey : key:'Key -> bool
  override Equals : obj -> bool
  member Remove : key:'Key -> Map<'Key,'Value>
  ...

Full name: Microsoft.FSharp.Collections.Map<_,_>

--------------------
new : elements:seq<'Key * 'Value> -> Map<'Key,'Value>
val ofSeq : elements:seq<'Key * 'T> -> Map<'Key,'T> (requires comparison)

Full name: Microsoft.FSharp.Collections.Map.ofSeq
val rule : Rule
val oldRules : seq<Rule>

Full name: Script.oldRules
Multiple items
type XDocument =
  inherit XContainer
  new : unit -> XDocument + 3 overloads
  member Declaration : XDeclaration with get, set
  member DocumentType : XDocumentType
  member NodeType : XmlNodeType
  member Root : XElement
  member Save : fileName:string -> unit + 6 overloads
  member WriteTo : writer:XmlWriter -> unit
  static member Load : uri:string -> XDocument + 7 overloads
  static member Parse : text:string -> XDocument + 1 overload

Full name: System.Xml.Linq.XDocument

--------------------
XDocument() : unit
XDocument([<System.ParamArray>] content: obj []) : unit
XDocument(other: XDocument) : unit
XDocument(declaration: XDeclaration, [<System.ParamArray>] content: obj []) : unit
XDocument.Parse(text: string) : XDocument
XDocument.Parse(text: string, options: LoadOptions) : XDocument
val xml : XDocument
XContainer.Descendants() : System.Collections.Generic.IEnumerable<XElement>
XContainer.Descendants(name: XName) : System.Collections.Generic.IEnumerable<XElement>
val el : XElement
XElement.Attribute(name: XName) : XAttribute
val document : XDocument

Full name: Script.document
val root : XElement

Full name: Script.root
property XDocument.Root: XElement
val styleCopNode : XElement option

Full name: Script.styleCopNode
val filter : predicate:('T -> bool) -> source:seq<'T> -> seq<'T>

Full name: Microsoft.FSharp.Collections.Seq.filter
val x : XElement
val tryHead : source:seq<'T> -> 'T option

Full name: Microsoft.FSharp.Collections.Seq.tryHead
val mutable existingRules : seq<Rule>

Full name: Script.existingRules
union case Option.Some: Value: 'T -> Option<'T>
val node : XElement
XNode.Remove() : unit
val ignore : value:'T -> unit

Full name: Microsoft.FSharp.Core.Operators.ignore
val empty<'T> : seq<'T>

Full name: Microsoft.FSharp.Collections.Seq.empty
val mutable matched : Rule list

Full name: Script.matched
Multiple items
module List

from Microsoft.FSharp.Collections

--------------------
type List<'T> =
  | ( [] )
  | ( :: ) of Head: 'T * Tail: 'T list
  interface IEnumerable
  interface IEnumerable<'T>
  member GetSlice : startIndex:int option * endIndex:int option -> 'T list
  member Head : 'T
  member IsEmpty : bool
  member Item : index:int -> 'T with get
  member Length : int
  member Tail : 'T list
  static member Cons : head:'T * tail:'T list -> 'T list
  static member Empty : 'T list

Full name: Microsoft.FSharp.Collections.List<_>
property List.Empty: 'T list
val mutable notMatched : Rule list

Full name: Script.notMatched
val tryFind : key:'Key -> table:Map<'Key,'T> -> 'T option (requires comparison)

Full name: Microsoft.FSharp.Collections.Map.tryFind
val x : Rule
val append : list1:'T list -> list2:'T list -> 'T list

Full name: Microsoft.FSharp.Collections.List.append
module Option

from Microsoft.FSharp.Core
val isNone : option:'T option -> bool

Full name: Microsoft.FSharp.Core.Option.isNone
val tryFind : predicate:('T -> bool) -> list:'T list -> 'T option

Full name: Microsoft.FSharp.Collections.List.tryFind
val append : source1:seq<'T> -> source2:seq<'T> -> seq<'T>

Full name: Microsoft.FSharp.Collections.Seq.append
XContainer.Add([<System.ParamArray>] content: obj []) : unit
XContainer.Add(content: obj) : unit
XDocument.Save(writer: System.Xml.XmlWriter) : unit
XDocument.Save(textWriter: TextWriter) : unit
XDocument.Save(stream: Stream) : unit
XDocument.Save(fileName: string) : unit
XDocument.Save(textWriter: TextWriter, options: SaveOptions) : unit
XDocument.Save(stream: Stream, options: SaveOptions) : unit
XDocument.Save(fileName: string, options: SaveOptions) : unit
val printfn : format:Printf.TextWriterFormat<'T> -> 'T

Full name: Microsoft.FSharp.Core.ExtraTopLevelOperators.printfn
property List.Length: int

More information

Link:http://fssnip.net/ss
Posted:6 years ago
Author:journeyman
Tags: stylecop , analyzers , vs2015