diff --git a/docs/input/guidelines/Analysers.md b/docs/input/guidelines/Analysers.md
new file mode 100644
index 0000000..c996298
--- /dev/null
+++ b/docs/input/guidelines/Analysers.md
@@ -0,0 +1,57 @@
+---
+Order: 3
+Title: Recommended References
+---
+
+
+
+## Table of Contents
+
+- [Goals](#goals)
+- [Related rules](#related-rules)
+- [Usage](#usage)
+- [Settings](#settings)
+ - [Opt-Out](#opt-out)
+
+
+
+## Goals
+
+To have consistency in code-style among the different tools/plugins the use of Analysers is recommended, especially the use of [StyleCop](https://github.com/DotNetAnalyzers/StyleCopAnalyzers). Additionally code-style anlysis using StyleCopy (and code generation in the IDE) should be properly configured using a `stylecop.json`-file as well as `.editorconfig`-file, respectively.
+
+Example-Files can be found at:
+
+* [`stylecop.json`](./examples/StyleCopJson.md)
+* [`.editorconfig`](./examples/Editorconfig.md)
+
+## Related rules
+
+ * [CCG0005](../rules/ccg0005)
+ * [CCG0006](../rules/ccg0006)
+
+## Usage
+
+Using this package automatically enables this guideline.
+
+## Settings
+
+### Opt-Out
+
+It it possible to opt-out of the check for StyleCop using the following setting:
+
+(*Keep in mind, though that it is not recommended to opt-out of this feature*)
+
+```xml
+
+
+
+```
+
+It is also possible to opt-out of the check for configuration-files (`stylecop.json` as well as `.editorconfig`)
+using the following settings:
+```xml
+
+
+
+
+```
diff --git a/docs/input/guidelines/examples/Editorconfig.md b/docs/input/guidelines/examples/Editorconfig.md
new file mode 100644
index 0000000..538d7eb
--- /dev/null
+++ b/docs/input/guidelines/examples/Editorconfig.md
@@ -0,0 +1,257 @@
+---
+Order: 1
+Title: Example for .editorconfig
+---
+
+
+
+## Table of Contents
+
+- [Example](#example)
+
+
+
+## Example
+
+```sh
+# C# files
+[*.cs]
+
+#### Core EditorConfig Options ####
+
+# Indentation and spacing
+indent_size = 4
+indent_style = space
+tab_width = 4
+
+# New line preferences
+end_of_line = crlf
+insert_final_newline = true
+
+#### .NET Coding Conventions ####
+
+# Organize usings
+dotnet_separate_import_directive_groups = true
+dotnet_sort_system_directives_first = true
+file_header_template = unset
+
+# this. and Me. preferences
+dotnet_style_qualification_for_event = false:warning
+dotnet_style_qualification_for_field = false:warning
+dotnet_style_qualification_for_method = false:warning
+dotnet_style_qualification_for_property = false:warning
+
+# Language keywords vs BCL types preferences
+dotnet_style_predefined_type_for_locals_parameters_members = true:warning
+dotnet_style_predefined_type_for_member_access = true:warning
+
+# Parentheses preferences
+dotnet_style_parentheses_in_arithmetic_binary_operators = always_for_clarity:silent
+dotnet_style_parentheses_in_other_binary_operators = always_for_clarity:silent
+dotnet_style_parentheses_in_other_operators = never_if_unnecessary:silent
+dotnet_style_parentheses_in_relational_binary_operators = always_for_clarity:silent
+
+# Modifier preferences
+dotnet_style_require_accessibility_modifiers = for_non_interface_members:warning
+
+# Expression-level preferences
+dotnet_style_coalesce_expression = true:suggestion
+dotnet_style_collection_initializer = true:suggestion
+dotnet_style_explicit_tuple_names = true:suggestion
+dotnet_style_null_propagation = true:suggestion
+dotnet_style_object_initializer = true:suggestion
+dotnet_style_operator_placement_when_wrapping = beginning_of_line
+dotnet_style_prefer_auto_properties = true:silent
+dotnet_style_prefer_compound_assignment = true:suggestion
+dotnet_style_prefer_conditional_expression_over_assignment = true:silent
+dotnet_style_prefer_conditional_expression_over_return = true:silent
+dotnet_style_prefer_inferred_anonymous_type_member_names = true:suggestion
+dotnet_style_prefer_inferred_tuple_names = true:suggestion
+dotnet_style_prefer_is_null_check_over_reference_equality_method = true:suggestion
+dotnet_style_prefer_simplified_boolean_expressions = true:suggestion
+dotnet_style_prefer_simplified_interpolation = true:suggestion
+
+# Field preferences
+dotnet_style_readonly_field = true:suggestion
+
+# Parameter preferences
+dotnet_code_quality_unused_parameters = all:suggestion
+
+#### C# Coding Conventions ####
+
+# var preferences
+csharp_style_var_elsewhere = false:silent
+csharp_style_var_for_built_in_types = false:silent
+csharp_style_var_when_type_is_apparent = false:silent
+
+# Expression-bodied members
+csharp_style_expression_bodied_accessors = true:silent
+csharp_style_expression_bodied_constructors = false:silent
+csharp_style_expression_bodied_indexers = true:silent
+csharp_style_expression_bodied_lambdas = true:silent
+csharp_style_expression_bodied_local_functions = false:silent
+csharp_style_expression_bodied_methods = false:silent
+csharp_style_expression_bodied_operators = false:silent
+csharp_style_expression_bodied_properties = true:silent
+
+# Pattern matching preferences
+csharp_style_pattern_matching_over_as_with_null_check = true:suggestion
+csharp_style_pattern_matching_over_is_with_cast_check = true:suggestion
+csharp_style_prefer_switch_expression = true:suggestion
+
+# Null-checking preferences
+csharp_style_conditional_delegate_call = true:suggestion
+
+# Modifier preferences
+csharp_prefer_static_local_function = true:suggestion
+csharp_preferred_modifier_order = public,private,protected,internal,static,extern,new,virtual,abstract,sealed,override,readonly,unsafe,volatile,async:silent
+
+# Code-block preferences
+csharp_prefer_braces = true:silent
+csharp_prefer_simple_using_statement = true:suggestion
+
+# Expression-level preferences
+csharp_prefer_simple_default_expression = true:suggestion
+csharp_style_deconstructed_variable_declaration = true:suggestion
+csharp_style_inlined_variable_declaration = true:suggestion
+csharp_style_pattern_local_over_anonymous_function = true:suggestion
+csharp_style_prefer_index_operator = true:suggestion
+csharp_style_prefer_range_operator = true:suggestion
+csharp_style_throw_expression = true:suggestion
+csharp_style_unused_value_assignment_preference = discard_variable:suggestion
+csharp_style_unused_value_expression_statement_preference = discard_variable:silent
+
+# 'using' directive preferences
+csharp_using_directive_placement = outside_namespace:warning
+
+#### C# Formatting Rules ####
+
+# New line preferences
+csharp_new_line_before_catch = true
+csharp_new_line_before_else = true
+csharp_new_line_before_finally = true
+csharp_new_line_before_members_in_anonymous_types = true
+csharp_new_line_before_members_in_object_initializers = true
+csharp_new_line_before_open_brace = all
+csharp_new_line_between_query_expression_clauses = true
+
+# Indentation preferences
+csharp_indent_block_contents = true
+csharp_indent_braces = false
+csharp_indent_case_contents = true
+csharp_indent_case_contents_when_block = false
+csharp_indent_labels = flush_left
+csharp_indent_switch_labels = true
+
+# Space preferences
+csharp_space_after_cast = false
+csharp_space_after_colon_in_inheritance_clause = true
+csharp_space_after_comma = true
+csharp_space_after_dot = false
+csharp_space_after_keywords_in_control_flow_statements = true
+csharp_space_after_semicolon_in_for_statement = true
+csharp_space_around_binary_operators = before_and_after
+csharp_space_around_declaration_statements = false
+csharp_space_before_colon_in_inheritance_clause = true
+csharp_space_before_comma = false
+csharp_space_before_dot = false
+csharp_space_before_open_square_brackets = false
+csharp_space_before_semicolon_in_for_statement = false
+csharp_space_between_empty_square_brackets = false
+csharp_space_between_method_call_empty_parameter_list_parentheses = false
+csharp_space_between_method_call_name_and_opening_parenthesis = false
+csharp_space_between_method_call_parameter_list_parentheses = false
+csharp_space_between_method_declaration_empty_parameter_list_parentheses = false
+csharp_space_between_method_declaration_name_and_open_parenthesis = false
+csharp_space_between_method_declaration_parameter_list_parentheses = false
+csharp_space_between_parentheses = false
+csharp_space_between_square_brackets = false
+
+# Wrapping preferences
+csharp_preserve_single_line_blocks = true
+csharp_preserve_single_line_statements = false
+
+#### Naming styles ####
+
+# Naming rules
+
+dotnet_naming_rule.interface_should_be_begins_with_i.severity = warning
+dotnet_naming_rule.interface_should_be_begins_with_i.symbols = interface
+dotnet_naming_rule.interface_should_be_begins_with_i.style = begins_with_i
+
+dotnet_naming_rule.types_should_be_pascal_case.severity = warning
+dotnet_naming_rule.types_should_be_pascal_case.symbols = types
+dotnet_naming_rule.types_should_be_pascal_case.style = pascal_case
+
+dotnet_naming_rule.method_should_be_pascal_case.severity = warning
+dotnet_naming_rule.method_should_be_pascal_case.symbols = method
+dotnet_naming_rule.method_should_be_pascal_case.style = pascal_case
+
+dotnet_naming_rule.public_or_protected_field_should_be_pascal_case.severity = warning
+dotnet_naming_rule.public_or_protected_field_should_be_pascal_case.symbols = public_or_protected_field
+dotnet_naming_rule.public_or_protected_field_should_be_pascal_case.style = pascal_case
+
+dotnet_naming_rule.private_or_internal_static_field_should_be_pascal_case.severity = warning
+dotnet_naming_rule.private_or_internal_static_field_should_be_pascal_case.symbols = private_or_internal_static_field
+dotnet_naming_rule.private_or_internal_static_field_should_be_pascal_case.style = pascal_case
+
+dotnet_naming_rule.private_or_internal_field_should_be_camelcase.severity = warning
+dotnet_naming_rule.private_or_internal_field_should_be_camelcase.symbols = private_or_internal_field
+dotnet_naming_rule.private_or_internal_field_should_be_camelcase.style = camelcase
+
+dotnet_naming_rule.non_field_members_should_be_pascal_case.severity = warning
+dotnet_naming_rule.non_field_members_should_be_pascal_case.symbols = non_field_members
+dotnet_naming_rule.non_field_members_should_be_pascal_case.style = pascal_case
+
+# Symbol specifications
+
+dotnet_naming_symbols.interface.applicable_kinds = interface
+dotnet_naming_symbols.interface.applicable_accessibilities = public, internal, private, protected, protected_internal, private_protected
+dotnet_naming_symbols.interface.required_modifiers =
+
+dotnet_naming_symbols.method.applicable_kinds = method
+dotnet_naming_symbols.method.applicable_accessibilities = public
+dotnet_naming_symbols.method.required_modifiers =
+
+dotnet_naming_symbols.public_or_protected_field.applicable_kinds = field
+dotnet_naming_symbols.public_or_protected_field.applicable_accessibilities = public, protected
+dotnet_naming_symbols.public_or_protected_field.required_modifiers =
+
+dotnet_naming_symbols.private_or_internal_field.applicable_kinds = field
+dotnet_naming_symbols.private_or_internal_field.applicable_accessibilities = internal, private, private_protected
+dotnet_naming_symbols.private_or_internal_field.required_modifiers =
+
+dotnet_naming_symbols.private_or_internal_static_field.applicable_kinds = field
+dotnet_naming_symbols.private_or_internal_static_field.applicable_accessibilities = internal, private, private_protected
+dotnet_naming_symbols.private_or_internal_static_field.required_modifiers = static
+
+dotnet_naming_symbols.types.applicable_kinds = class, struct, interface, enum
+dotnet_naming_symbols.types.applicable_accessibilities = public, internal, private, protected, protected_internal, private_protected
+dotnet_naming_symbols.types.required_modifiers =
+
+dotnet_naming_symbols.non_field_members.applicable_kinds = property, event, method
+dotnet_naming_symbols.non_field_members.applicable_accessibilities = public, internal, private, protected, protected_internal, private_protected
+dotnet_naming_symbols.non_field_members.required_modifiers =
+
+# Naming styles
+
+dotnet_naming_style.pascal_case.required_prefix =
+dotnet_naming_style.pascal_case.required_suffix =
+dotnet_naming_style.pascal_case.word_separator =
+dotnet_naming_style.pascal_case.capitalization = pascal_case
+
+dotnet_naming_style.begins_with_i.required_prefix = I
+dotnet_naming_style.begins_with_i.required_suffix =
+dotnet_naming_style.begins_with_i.word_separator =
+dotnet_naming_style.begins_with_i.capitalization = pascal_case
+
+dotnet_naming_style.camelcase.required_prefix =
+dotnet_naming_style.camelcase.required_suffix =
+dotnet_naming_style.camelcase.word_separator =
+dotnet_naming_style.camelcase.capitalization = camel_case
+
+# Rules:
+
+# SA1101: Prefix local calls with this
+dotnet_diagnostic.SA1101.severity = none
+```
\ No newline at end of file
diff --git a/docs/input/guidelines/examples/StyleCopJson.md b/docs/input/guidelines/examples/StyleCopJson.md
new file mode 100644
index 0000000..5e02e6f
--- /dev/null
+++ b/docs/input/guidelines/examples/StyleCopJson.md
@@ -0,0 +1,36 @@
+---
+Order: 2
+Title: Example for stylecop.json
+---
+
+
+
+## Table of Contents
+
+- [Example](#example)
+
+
+
+## Example
+
+```json
+{
+ "$schema": "https://raw.githubusercontent.com/DotNetAnalyzers/StyleCopAnalyzers/master/StyleCop.Analyzers/StyleCop.Analyzers/Settings/stylecop.schema.json",
+ "settings": {
+ "indentation": {
+ "indentationSize": 4,
+ "tabSize": 4,
+ "useTabs": false
+ },
+ "orderingRules": {
+ "usingDirectivesPlacement": "outsideNamespace",
+ "blankLinesBetweenUsingGroups": "allow",
+ "systemUsingDirectivesFirst": true
+ },
+ "documentationRules": {
+ "xmlHeader": false
+ }
+ }
+}
+
+```
\ No newline at end of file
diff --git a/docs/input/rules/ccg0005.md b/docs/input/rules/ccg0005.md
new file mode 100644
index 0000000..7cfb2d2
--- /dev/null
+++ b/docs/input/rules/ccg0005.md
@@ -0,0 +1,35 @@
+---
+Order: 5
+Title: CCG0005
+Description: Usage of analysers is recommended
+---
+
+ > No reference to `StyleCop.Analyzers` found. Usage of `StyleCop.Analyzers` is strongly recommended.
+
+
+
+## Table of Contents
+
+- [Cause](#cause)
+- [Description](#description)
+- [How to fix violations](#how-to-fix-violations)
+- [Related guidelines](#related-guidelines)
+
+
+
+## Cause
+
+This warning is raised, when the recommended analyser [StyleCop](https://github.com/DotNetAnalyzers/StyleCopAnalyzers) is not referenced.
+
+## Description
+
+Usage of [StyleCop](https://github.com/DotNetAnalyzers/StyleCopAnalyzers) is recommended.
+
+## How to fix violations
+
+Add a reference to [StyleCop](https://github.com/DotNetAnalyzers/StyleCopAnalyzers).
+(Or opt-out of this rule, by setting `CakeContribGuidelinesOmitRecommendedReference`)
+
+## Related guidelines
+
+* [Usage of Analysers](../guidelines/Analysers)
\ No newline at end of file
diff --git a/docs/input/rules/ccg0006.md b/docs/input/rules/ccg0006.md
new file mode 100644
index 0000000..f3c7e0e
--- /dev/null
+++ b/docs/input/rules/ccg0006.md
@@ -0,0 +1,42 @@
+---
+Order: 6
+Title: CCG0006
+Description: Missing recommended configuraion-file
+---
+
+ > No reference to `.editorconfig` found. Usage of `.editorconfig` is strongly recommended.
+
+
+
+## Table of Contents
+
+- [Cause](#cause)
+- [Description](#description)
+- [How to fix violations](#how-to-fix-violations)
+- [Related guidelines](#related-guidelines)
+
+
+
+## Cause
+
+This warning is raised, when a recommended configuration-file (i.e. `stylecop.json` or `.editorconfig`) can not be found.
+
+## Description
+
+Code-Formatting and layout should be properly configured. This is done using
+blah and blah.
+
+## How to fix violations
+
+Add a balh and blah to the project.
+
+Example-Files can be found at:
+
+* [`stylecop.json`](../guidelines/examples/StyleCopJson.md)
+* [`.editorconfig`](../guidelines/examples/Editorconfig.md)
+
+(Or opt-out of this rule, by setting `CakeContribGuidelinesOmitRecommendedConfigFile`)
+
+## Related guidelines
+
+* [Usage of Analysers](../guidelines/Analysers)
\ No newline at end of file
diff --git a/e2e-tests/CCG0001/Default/Default.csproj b/e2e-tests/CCG0001/Default/Default.csproj
index 121c486..5195768 100644
--- a/e2e-tests/CCG0001/Default/Default.csproj
+++ b/e2e-tests/CCG0001/Default/Default.csproj
@@ -5,7 +5,13 @@
-
+
+ runtime; build; native; contentfiles; analyzers; buildtransitive
+ all
+
+
+
+
diff --git a/e2e-tests/CCG0002/Default/Default.csproj b/e2e-tests/CCG0002/Default/Default.csproj
index 1973cca..dd0939e 100644
--- a/e2e-tests/CCG0002/Default/Default.csproj
+++ b/e2e-tests/CCG0002/Default/Default.csproj
@@ -5,4 +5,14 @@
$(CakeContribGuidelinesIconDestinationLocation)
+
+
+ runtime; build; native; contentfiles; analyzers; buildtransitive
+ all
+
+
+
+
+
+
diff --git a/e2e-tests/CCG0003/Default/Default.csproj b/e2e-tests/CCG0003/Default/Default.csproj
index ac4e6eb..2c720d1 100644
--- a/e2e-tests/CCG0003/Default/Default.csproj
+++ b/e2e-tests/CCG0003/Default/Default.csproj
@@ -6,4 +6,14 @@
https://project/path/to/icon
+
+
+ runtime; build; native; contentfiles; analyzers; buildtransitive
+ all
+
+
+
+
+
+
diff --git a/e2e-tests/CCG0003/ModifiedPath/ModifiedPath.csproj b/e2e-tests/CCG0003/ModifiedPath/ModifiedPath.csproj
index 289df4a..b934978 100644
--- a/e2e-tests/CCG0003/ModifiedPath/ModifiedPath.csproj
+++ b/e2e-tests/CCG0003/ModifiedPath/ModifiedPath.csproj
@@ -7,4 +7,14 @@
https://project/path/to/icon
+
+
+ runtime; build; native; contentfiles; analyzers; buildtransitive
+ all
+
+
+
+
+
+
diff --git a/e2e-tests/CCG0004/Default/Default.csproj b/e2e-tests/CCG0004/Default/Default.csproj
index d80cb40..5633571 100644
--- a/e2e-tests/CCG0004/Default/Default.csproj
+++ b/e2e-tests/CCG0004/Default/Default.csproj
@@ -8,6 +8,13 @@
+
+ runtime; build; native; contentfiles; analyzers; buildtransitive
+ all
+
+
+
+
diff --git a/e2e-tests/CCG0004/NoPrivateAssets/NoPrivateAssets.csproj b/e2e-tests/CCG0004/NoPrivateAssets/NoPrivateAssets.csproj
index b995910..7dcb680 100644
--- a/e2e-tests/CCG0004/NoPrivateAssets/NoPrivateAssets.csproj
+++ b/e2e-tests/CCG0004/NoPrivateAssets/NoPrivateAssets.csproj
@@ -8,6 +8,13 @@
+
+ runtime; build; native; contentfiles; analyzers; buildtransitive
+ all
+
+
+
+
diff --git a/e2e-tests/CCG0005/Default/Default.csproj b/e2e-tests/CCG0005/Default/Default.csproj
new file mode 100644
index 0000000..282a556
--- /dev/null
+++ b/e2e-tests/CCG0005/Default/Default.csproj
@@ -0,0 +1,13 @@
+
+
+
+ netstandard2.0
+ $(CakeContribGuidelinesIconDestinationLocation)
+ https://project/path/to/icon
+
+
+
+
+
+
+
diff --git a/e2e-tests/CCG0005/Default/spec.json b/e2e-tests/CCG0005/Default/spec.json
new file mode 100644
index 0000000..a12e46c
--- /dev/null
+++ b/e2e-tests/CCG0005/Default/spec.json
@@ -0,0 +1,6 @@
+{
+ "description": "not referencing StyleCop.Analyzers yields a warning",
+ "exitCode": 0,
+ "errors": [],
+ "warnings": [ "CCG0005" ]
+}
diff --git a/e2e-tests/CCG0005/OmittingStyleCop/OmittingStyleCop.csproj b/e2e-tests/CCG0005/OmittingStyleCop/OmittingStyleCop.csproj
new file mode 100644
index 0000000..5c1b529
--- /dev/null
+++ b/e2e-tests/CCG0005/OmittingStyleCop/OmittingStyleCop.csproj
@@ -0,0 +1,13 @@
+
+
+
+ netstandard2.0
+ $(CakeContribGuidelinesIconDestinationLocation)
+ https://project/path/to/icon
+
+
+
+
+
+
+
diff --git a/e2e-tests/CCG0005/OmittingStyleCop/spec.json b/e2e-tests/CCG0005/OmittingStyleCop/spec.json
new file mode 100644
index 0000000..3ac9f4c
--- /dev/null
+++ b/e2e-tests/CCG0005/OmittingStyleCop/spec.json
@@ -0,0 +1,6 @@
+{
+ "description": "omitting StyleCop.Analyzers yields no warning",
+ "exitCode": 0,
+ "errors": [],
+ "warnings": [ ]
+}
diff --git a/e2e-tests/CCG0006/Default/Default.csproj b/e2e-tests/CCG0006/Default/Default.csproj
new file mode 100644
index 0000000..184733a
--- /dev/null
+++ b/e2e-tests/CCG0006/Default/Default.csproj
@@ -0,0 +1,16 @@
+
+
+
+ netstandard2.0
+ $(CakeContribGuidelinesIconDestinationLocation)
+ https://project/path/to/icon
+
+
+
+
+ runtime; build; native; contentfiles; analyzers; buildtransitive
+ all
+
+
+
+
diff --git a/e2e-tests/CCG0006/Default/spec.json b/e2e-tests/CCG0006/Default/spec.json
new file mode 100644
index 0000000..adfe77d
--- /dev/null
+++ b/e2e-tests/CCG0006/Default/spec.json
@@ -0,0 +1,6 @@
+{
+ "description": "not referencing stylecop.json yields a warning",
+ "exitCode": 0,
+ "errors": [],
+ "warnings": [ "CCG0006" ]
+}
diff --git a/recipe.cake b/recipe.cake
index a6a0212..94297ea 100644
--- a/recipe.cake
+++ b/recipe.cake
@@ -21,7 +21,8 @@ ToolSettings.SetToolSettings(
context: Context,
dupFinderExcludePattern: new string[]
{
- $"{BuildParameters.RootDirectoryPath}/{BuildParameters.SourceDirectoryPath}/**/*.AssemblyInfo.cs"
+ $"{BuildParameters.RootDirectoryPath}/{BuildParameters.SourceDirectoryPath}/**/*.AssemblyInfo.cs",
+ $"{BuildParameters.RootDirectoryPath}/{BuildParameters.SourceDirectoryPath}/Tasks.Tests/**/*.cs"
});
Build.RunDotNetCore();
diff --git a/src/.editorconfig b/src/.editorconfig
index fac77b2..9151f22 100644
--- a/src/.editorconfig
+++ b/src/.editorconfig
@@ -236,17 +236,14 @@ dotnet_naming_style.camelcase.capitalization = camel_case
# other Rules:
-# all dll shoul have documentaion
+# all dll should have documentaion - there's no need here. This dll is only consumed here..
dotnet_diagnostic.SA0001.severity = none
-# files should have a header
+# files should have a header - maybe they should - need to think about this.
dotnet_diagnostic.SA1633.severity = none
# use this.
dotnet_diagnostic.SA1101.severity = none
-# usings inside namespace
-dotnet_diagnostic.SA1200.severity = none
-
-# CA1819: Properties should not return arrays
+# CA1819: Properties should not return arrays - for MSBuild, they have to.
dotnet_diagnostic.CA1819.severity = none
diff --git a/src/CakeContrib.Guidelines.sln b/src/CakeContrib.Guidelines.sln
index 4576dd6..8b32e62 100644
--- a/src/CakeContrib.Guidelines.sln
+++ b/src/CakeContrib.Guidelines.sln
@@ -10,11 +10,6 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Guidelines", "Guidelines\Gu
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Tasks", "Tasks\Tasks.csproj", "{9A14DE98-8373-4BEE-B564-FC980B1D1396}"
EndProject
-Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{FF2678E5-CEAB-425C-B2FB-E3C1E92C70EF}"
- ProjectSection(SolutionItems) = preProject
- .editorconfig = .editorconfig
- EndProjectSection
-EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Tasks.Tests", "Tasks.Tests\Tasks.Tests.csproj", "{1892704F-77DA-495D-AC15-2304E18E88F2}"
EndProject
Global
diff --git a/src/Guidelines/Guidelines.csproj b/src/Guidelines/Guidelines.csproj
index 564f4d3..965a181 100644
--- a/src/Guidelines/Guidelines.csproj
+++ b/src/Guidelines/Guidelines.csproj
@@ -36,8 +36,4 @@
-
-
-
-
-
+
\ No newline at end of file
diff --git a/src/Guidelines/build/CakeContrib.Guidelines.targets b/src/Guidelines/build/CakeContrib.Guidelines.targets
index 8a44a10..da22dc5 100644
--- a/src/Guidelines/build/CakeContrib.Guidelines.targets
+++ b/src/Guidelines/build/CakeContrib.Guidelines.targets
@@ -1,10 +1,12 @@
-
-
-
\ No newline at end of file
+
+
+
+
diff --git a/src/Guidelines/build/CakeReference.targets b/src/Guidelines/build/PrivateAssets.targets
similarity index 90%
rename from src/Guidelines/build/CakeReference.targets
rename to src/Guidelines/build/PrivateAssets.targets
index 583a613..aea658b 100644
--- a/src/Guidelines/build/CakeReference.targets
+++ b/src/Guidelines/build/PrivateAssets.targets
@@ -1,12 +1,12 @@
-
+
@@ -22,5 +22,4 @@
References="@(PackageReference)"
ProjectFile="$(MSBuildProjectFullPath)" />
-
diff --git a/src/Guidelines/build/RequiredFiles.targets b/src/Guidelines/build/RequiredFiles.targets
new file mode 100644
index 0000000..9ce0465
--- /dev/null
+++ b/src/Guidelines/build/RequiredFiles.targets
@@ -0,0 +1,25 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/Guidelines/build/RequiredReferences.targets b/src/Guidelines/build/RequiredReferences.targets
new file mode 100644
index 0000000..5423b86
--- /dev/null
+++ b/src/Guidelines/build/RequiredReferences.targets
@@ -0,0 +1,22 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/Tasks.Tests/E2eTests.cs b/src/Tasks.Tests/E2eTests.cs
index 9a563ed..4084180 100644
--- a/src/Tasks.Tests/E2eTests.cs
+++ b/src/Tasks.Tests/E2eTests.cs
@@ -61,7 +61,11 @@ public void Should_Pass_All_E3E_Tests_using_Framework(string projFile, Spec spec
ErrorDialog = false,
WorkingDirectory = Environment.CurrentDirectory,
FileName = "dotnet",
+#if NETCORE
+ Arguments = "build " + projFile
+#else
Arguments = "msbuild " + projFile
+#endif
};
var exitcode = -1;
diff --git a/src/Tasks.Tests/Fixtures/BaseBuildFixture.cs b/src/Tasks.Tests/Fixtures/BaseBuildFixture.cs
new file mode 100644
index 0000000..d54d979
--- /dev/null
+++ b/src/Tasks.Tests/Fixtures/BaseBuildFixture.cs
@@ -0,0 +1,37 @@
+using Microsoft.Build.Framework;
+using Microsoft.Build.Utilities;
+
+using Moq;
+
+namespace CakeContrib.Guidelines.Tasks.Tests.Fixtures
+{
+ public class BaseBuildFixture
+ where T : Task, new()
+ {
+ public MockBuildEngine BuildEngine { get; }
+
+ protected T Task { get; }
+
+ protected Mock GetMockTaskItem(string identity)
+ {
+ var item = new Mock();
+ item.Setup(x => x.ToString()).Returns(identity);
+ item.Setup(x => x.GetMetadata("Identity")).Returns(identity);
+ return item;
+ }
+
+ public BaseBuildFixture()
+ {
+ BuildEngine = new MockBuildEngine();
+ Task = new T
+ {
+ BuildEngine = BuildEngine
+ };
+ }
+
+ public virtual bool Execute()
+ {
+ return Task.Execute();
+ }
+ }
+}
diff --git a/src/Tasks.Tests/Fixtures/CheckPrivateAssetsOnReferencesFixture.cs b/src/Tasks.Tests/Fixtures/CheckPrivateAssetsOnReferencesFixture.cs
index 10dbf32..91e7d60 100644
--- a/src/Tasks.Tests/Fixtures/CheckPrivateAssetsOnReferencesFixture.cs
+++ b/src/Tasks.Tests/Fixtures/CheckPrivateAssetsOnReferencesFixture.cs
@@ -6,35 +6,22 @@
namespace CakeContrib.Guidelines.Tasks.Tests.Fixtures
{
- public class CheckPrivateAssetsOnReferencesFixture
+ public class CheckPrivateAssetsOnReferencesFixture : BaseBuildFixture
{
- public MockBuildEngine BuildEngine { get; }
-
- private readonly CheckPrivateAssetsOnReferences task;
- private readonly List references;
private readonly List packagesToCheck;
+ private readonly List references;
public CheckPrivateAssetsOnReferencesFixture()
{
- BuildEngine = new MockBuildEngine();
- task = new CheckPrivateAssetsOnReferences
- {
- BuildEngine = BuildEngine
- };
- packagesToCheck = new List();
references = new List();
+ packagesToCheck = new List();
}
- public bool Execute()
- {
- task.References = references.ToArray();
- task.PackagesToCheck = packagesToCheck.ToArray();
- return task.Execute();
- }
-
- public void WithProjectFile(string fileName)
+ public override bool Execute()
{
- task.ProjectFile = fileName;
+ Task.References = references.ToArray();
+ Task.PackagesToCheck = packagesToCheck.ToArray();
+ return base.Execute();
}
public void WithPackageToCheck(string packageName)
@@ -44,6 +31,11 @@ public void WithPackageToCheck(string packageName)
packagesToCheck.Add(packageToCheck.Object);
}
+ public void WithProjectFile(string fileName)
+ {
+ Task.ProjectFile = fileName;
+ }
+
public void WithReferencedPackage(string packageName, string privateAssets = "")
{
var referencedPackage = new Mock();
diff --git a/src/Tasks.Tests/Fixtures/RequiredFileStylecopJsonFixture.cs b/src/Tasks.Tests/Fixtures/RequiredFileStylecopJsonFixture.cs
new file mode 100644
index 0000000..2bb8beb
--- /dev/null
+++ b/src/Tasks.Tests/Fixtures/RequiredFileStylecopJsonFixture.cs
@@ -0,0 +1,44 @@
+using System.Collections.Generic;
+
+using Microsoft.Build.Framework;
+
+using Moq;
+
+namespace CakeContrib.Guidelines.Tasks.Tests.Fixtures
+{
+ public class RequiredFileStylecopJsonFixture : BaseBuildFixture
+ {
+ private readonly List additionalFiles;
+ private readonly List omittedFiles;
+
+ public RequiredFileStylecopJsonFixture()
+ {
+ additionalFiles = new List();
+ omittedFiles = new List();
+ }
+
+ public override bool Execute()
+ {
+ Task.AdditionalFiles = additionalFiles.ToArray();
+ Task.OmitFiles = omittedFiles.ToArray();
+ return base.Execute();
+ }
+
+ public void WithAdditionalFile(string filePath)
+ {
+ var item = GetMockTaskItem(filePath);
+ item.Setup(x => x.GetMetadata("FullPath")).Returns(filePath);
+ additionalFiles.Add(item.Object);
+ }
+
+ public void WithOmittedFile(string id)
+ {
+ omittedFiles.Add(GetMockTaskItem(id).Object);
+ }
+
+ public void WithProjectFile(string fileName)
+ {
+ Task.ProjectFile = fileName;
+ }
+ }
+}
diff --git a/src/Tasks.Tests/Fixtures/RequiredReferencesFixture.cs b/src/Tasks.Tests/Fixtures/RequiredReferencesFixture.cs
new file mode 100644
index 0000000..104a63e
--- /dev/null
+++ b/src/Tasks.Tests/Fixtures/RequiredReferencesFixture.cs
@@ -0,0 +1,57 @@
+using System.Collections.Generic;
+
+using Microsoft.Build.Framework;
+
+using Moq;
+
+namespace CakeContrib.Guidelines.Tasks.Tests.Fixtures
+{
+ public class RequiredReferencesFixture : BaseBuildFixture
+ {
+ private readonly List requiredReferences;
+ private readonly List omittedReferences;
+ private readonly List references;
+
+ public RequiredReferencesFixture()
+ {
+ references = new List();
+ requiredReferences = new List();
+ omittedReferences = new List();
+ }
+
+ public override bool Execute()
+ {
+ Task.References = references.ToArray();
+ Task.Required = requiredReferences.ToArray();
+ Task.Omitted = omittedReferences.ToArray();
+ return base.Execute();
+ }
+
+ public void WithRequiredReferences(string packageName)
+ {
+ var reference = new Mock();
+ reference.Setup(x => x.ToString()).Returns(packageName);
+ requiredReferences.Add(reference.Object);
+ }
+
+ public void WithOmittedReferences(string packageName)
+ {
+ var reference = new Mock();
+ reference.Setup(x => x.ToString()).Returns(packageName);
+ omittedReferences.Add(reference.Object);
+ }
+
+ public void WithProjectFile(string fileName)
+ {
+ Task.ProjectFile = fileName;
+ }
+
+ public void WithReferencedPackage(string packageName, string privateAssets = "")
+ {
+ var referencedPackage = new Mock();
+ referencedPackage.Setup(x => x.ToString()).Returns(packageName);
+ referencedPackage.Setup(x => x.GetMetadata("PrivateAssets")).Returns(privateAssets);
+ references.Add(referencedPackage.Object);
+ }
+ }
+}
diff --git a/src/Tasks.Tests/IntegrationTests/SimpleTest.cs b/src/Tasks.Tests/IntegrationTests/SimpleTest.cs
deleted file mode 100644
index a685a8f..0000000
--- a/src/Tasks.Tests/IntegrationTests/SimpleTest.cs
+++ /dev/null
@@ -1,10 +0,0 @@
-using System;
-using System.Collections.Generic;
-using System.Text;
-
-namespace CakeContrib.Guidelines.Tasks.Tests.IntegrationTests
-{
- public class SimpleTest
- {
- }
-}
diff --git a/src/Tasks.Tests/RequiredFilesTests.cs b/src/Tasks.Tests/RequiredFilesTests.cs
new file mode 100644
index 0000000..1fce79c
--- /dev/null
+++ b/src/Tasks.Tests/RequiredFilesTests.cs
@@ -0,0 +1,59 @@
+using System.Linq;
+
+using CakeContrib.Guidelines.Tasks.Tests.Fixtures;
+
+using FluentAssertions;
+
+using Xunit;
+
+namespace CakeContrib.Guidelines.Tasks.Tests
+{
+ public class RequiredFilesTests
+ {
+ // TODO: Use https://github.com/System-IO-Abstractions/System.IO.Abstractions
+ // to test the editorconfig-task?
+
+ [Fact]
+ public void RequiredStylecopJson_Should_Not_Warn_If_StylecopJson_Is_Referenced()
+ {
+ // given
+ var fixture = new RequiredFileStylecopJsonFixture();
+ fixture.WithAdditionalFile("some/path/to/a/stylecop.json");
+
+ // when
+ fixture.Execute();
+
+ // then
+ fixture.BuildEngine.WarningEvents.Should().HaveCount(0);
+ }
+
+ [Fact]
+ public void RequiredStylecopJson_Should_Warn_If_No_StylecopJson_Is_Referenced()
+ {
+ // given
+ var fixture = new RequiredFileStylecopJsonFixture();
+
+ // when
+ fixture.Execute();
+
+ // then
+ fixture.BuildEngine.WarningEvents.Should().HaveCount(1);
+ var theEvent = fixture.BuildEngine.WarningEvents.Single();
+ theEvent.Code.Should().Be("CCG0006");
+ }
+
+ [Fact]
+ public void RequiredStylecopJson_Should_Not_Warn_If_StylecopJson_Is_Omitted()
+ {
+ // given
+ var fixture = new RequiredFileStylecopJsonFixture();
+ fixture.WithOmittedFile("stylecop.json");
+
+ // when
+ fixture.Execute();
+
+ // then
+ fixture.BuildEngine.WarningEvents.Should().HaveCount(0);
+ }
+ }
+}
diff --git a/src/Tasks.Tests/RequiredReferencesTests.cs b/src/Tasks.Tests/RequiredReferencesTests.cs
new file mode 100644
index 0000000..54b98fd
--- /dev/null
+++ b/src/Tasks.Tests/RequiredReferencesTests.cs
@@ -0,0 +1,63 @@
+using System.Linq;
+
+using CakeContrib.Guidelines.Tasks.Tests.Fixtures;
+
+using FluentAssertions;
+
+using Xunit;
+
+namespace CakeContrib.Guidelines.Tasks.Tests
+{
+ public class RequiredReferencesTests
+ {
+ [Fact]
+ public void Should_Not_Warn_If_RequiredPackage_Is_Referenced()
+ {
+ // given
+ const string required = "Some.Analyser";
+ var fixture = new RequiredReferencesFixture();
+ fixture.WithReferencedPackage(required);
+ fixture.WithRequiredReferences(required);
+
+ // when
+ fixture.Execute();
+
+ // then
+ fixture.BuildEngine.WarningEvents.Should().HaveCount(0);
+ }
+
+ [Fact]
+ public void Should_Warn_If_RequiredPackage_Is_Not_Referenced()
+ {
+ // given
+ var fixture = new RequiredReferencesFixture();
+ fixture.WithReferencedPackage("Cool.Ref.Project");
+ fixture.WithRequiredReferences("Some.Analyser");
+
+ // when
+ var actual = fixture.Execute();
+
+ // then
+ fixture.BuildEngine.WarningEvents.Should().HaveCount(1);
+ var theEvent = fixture.BuildEngine.WarningEvents.Single();
+ theEvent.Code.Should().Be("CCG0005");
+ }
+
+ [Fact]
+ public void Should_Not_Warn_If_RequiredPackage_Is_Omitted()
+ {
+ // given
+ const string required = "Some.Analyser";
+ var fixture = new RequiredReferencesFixture();
+ fixture.WithReferencedPackage("Cool.Ref.Project");
+ fixture.WithRequiredReferences(required);
+ fixture.WithOmittedReferences(required);
+
+ // when
+ var actual = fixture.Execute();
+
+ // then
+ fixture.BuildEngine.WarningEvents.Should().HaveCount(0);
+ }
+ }
+}
diff --git a/src/Tasks.Tests/Tasks.Tests.csproj b/src/Tasks.Tests/Tasks.Tests.csproj
index 23b8fbc..3a26c54 100644
--- a/src/Tasks.Tests/Tasks.Tests.csproj
+++ b/src/Tasks.Tests/Tasks.Tests.csproj
@@ -8,6 +8,13 @@
false
+
+ $(DefineConstants);NETFRAMEWORK
+
+
+ $(DefineConstants);NETCORE
+
+
runtime; build; native; contentfiles; analyzers; buildtransitive
@@ -41,4 +48,4 @@
-
\ No newline at end of file
+
diff --git a/src/Tasks/RequiredFileEditorconfig.cs b/src/Tasks/RequiredFileEditorconfig.cs
new file mode 100644
index 0000000..bbc6b90
--- /dev/null
+++ b/src/Tasks/RequiredFileEditorconfig.cs
@@ -0,0 +1,68 @@
+using System;
+using System.IO;
+using System.Linq;
+using System.Security.Cryptography.X509Certificates;
+
+using Microsoft.Build.Framework;
+using Microsoft.Build.Utilities;
+
+namespace CakeContrib.Guidelines.Tasks
+{
+ ///
+ /// The Task to check for editorconfig for the guideline .
+ ///
+ public class RequiredFileEditorconfig : Task
+ {
+ private const string FileName = ".editorconfig";
+
+ ///
+ /// Gets or sets the project file.
+ ///
+ [Required]
+ public string ProjectFile { get; set; }
+
+ ///
+ /// Gets or sets the files to omit.
+ ///
+ [Required]
+ public ITaskItem[] OmitFiles { get; set; }
+
+ ///
+ public override bool Execute()
+ {
+ if (OmitFiles
+ .Select(x => x.GetMetadata("Identity"))
+ .Where(x => !string.IsNullOrEmpty(x))
+ .Any(x => x.Equals(FileName, StringComparison.OrdinalIgnoreCase)))
+ {
+ Log.LogMessage(MessageImportance.Low, $"Recommended file '{FileName}' is set to omit.");
+ return true;
+ }
+
+ var folder = Path.GetDirectoryName(ProjectFile);
+ var found = false;
+ while (folder != null && !found)
+ {
+ found = File.Exists(Path.Combine(folder, FileName));
+ if (found)
+ {
+ return true;
+ }
+
+ folder = Path.GetDirectoryName(folder);
+ }
+
+ Log.LogWarning(
+ null,
+ "CCG0006",
+ string.Empty, // TODO: Can we get HelpLink like in roslyn analysers?
+ ProjectFile,
+ 0,
+ 0,
+ 0,
+ 0,
+ $"No '{FileName}' found in folder-structure. Usage of '{FileName}' is strongly recommended.");
+ return true;
+ }
+ }
+}
diff --git a/src/Tasks/RequiredFileStylecopJson.cs b/src/Tasks/RequiredFileStylecopJson.cs
new file mode 100644
index 0000000..0fd80af
--- /dev/null
+++ b/src/Tasks/RequiredFileStylecopJson.cs
@@ -0,0 +1,78 @@
+using System;
+using System.IO;
+using System.Linq;
+
+using Microsoft.Build.Framework;
+using Microsoft.Build.Utilities;
+
+namespace CakeContrib.Guidelines.Tasks
+{
+ ///
+ /// The Task to check for stylecop.json for the guideline .
+ ///
+ public class RequiredFileStylecopJson : Task
+ {
+ private const string SettingsFileName = "stylecop.json";
+ private const string AltSettingsFileName = ".stylecop.json";
+
+ ///
+ /// Gets or sets the project file.
+ ///
+ public string ProjectFile { get; set; }
+
+ ///
+ /// Gets or sets the AdditionalFiles to check.
+ ///
+ [Required]
+ public ITaskItem[] AdditionalFiles { get; set; }
+
+ ///
+ /// Gets or sets the files to omit.
+ ///
+ [Required]
+ public ITaskItem[] OmitFiles { get; set; }
+
+ ///
+ public override bool Execute()
+ {
+ if (OmitFiles
+ .Select(x => x.GetMetadata("Identity"))
+ .Where(x => !string.IsNullOrEmpty(x))
+ .Any(x => x.Equals(SettingsFileName, StringComparison.OrdinalIgnoreCase) ||
+ x.Equals(AltSettingsFileName, StringComparison.OrdinalIgnoreCase)))
+ {
+ Log.LogMessage(MessageImportance.Low, $"Recommended file '{SettingsFileName}' is set to omit.");
+ return true;
+ }
+
+ foreach (var file in AdditionalFiles)
+ {
+ var fullPath = file.GetMetadata("FullPath");
+ if (string.IsNullOrEmpty(fullPath))
+ {
+ continue;
+ }
+
+ var refFileName = Path.GetFileName(fullPath);
+ if (refFileName.Equals(SettingsFileName, StringComparison.OrdinalIgnoreCase) ||
+ refFileName.Equals(AltSettingsFileName, StringComparison.OrdinalIgnoreCase))
+ {
+ return true;
+ }
+ }
+
+ Log.LogWarning(
+ null,
+ "CCG0006",
+ string.Empty, // TODO: Can we get HelpLink like in roslyn analysers?
+ ProjectFile ?? string.Empty,
+ 0,
+ 0,
+ 0,
+ 0,
+ $"No reference to '{SettingsFileName}' found. Usage of '{SettingsFileName}' is strongly recommended.");
+
+ return true;
+ }
+ }
+}
diff --git a/src/Tasks/RequiredReferences.cs b/src/Tasks/RequiredReferences.cs
new file mode 100644
index 0000000..c319913
--- /dev/null
+++ b/src/Tasks/RequiredReferences.cs
@@ -0,0 +1,70 @@
+using System;
+using System.Linq;
+
+using Microsoft.Build.Framework;
+using Microsoft.Build.Utilities;
+
+namespace CakeContrib.Guidelines.Tasks
+{
+ ///
+ /// The Task to check for References for the guideline .
+ ///
+ public class RequiredReferences : Task
+ {
+ ///
+ /// Gets or sets the References.
+ ///
+ [Required]
+ public ITaskItem[] References { get; set; }
+
+ ///
+ /// Gets or sets the Packages to check.
+ ///
+ [Required]
+ public ITaskItem[] Required { get; set; }
+
+ ///
+ /// Gets or sets the Packages to check.
+ ///
+ [Required]
+ public ITaskItem[] Omitted { get; set; }
+
+ ///
+ /// Gets or sets the project file.
+ ///
+ public string ProjectFile { get; set; }
+
+ ///
+ public override bool Execute()
+ {
+ foreach (var r in Required)
+ {
+ if (Omitted.Any(x => x.ToString().Equals(r.ToString(), StringComparison.OrdinalIgnoreCase)))
+ {
+ Log.LogMessage(MessageImportance.Low, $"Required reference '{r}' is set to omit.");
+ continue;
+ }
+
+ Log.LogMessage(MessageImportance.Low, $"Checking required reference: {r}");
+ if (References.Any(x => x.ToString().Equals(r.ToString(), StringComparison.OrdinalIgnoreCase)))
+ {
+ // found.
+ continue;
+ }
+
+ Log.LogWarning(
+ null,
+ "CCG0005",
+ string.Empty, // TODO: Can we get HelpLink like in roslyn analysers?
+ ProjectFile ?? string.Empty,
+ 0,
+ 0,
+ 0,
+ 0,
+ $"No reference to '{r}' found. Usage of '{r}' is strongly recommended");
+ }
+
+ return true;
+ }
+ }
+}
diff --git a/src/Tasks/Tasks.csproj b/src/Tasks/Tasks.csproj
index e1d77bb..a8ac80d 100644
--- a/src/Tasks/Tasks.csproj
+++ b/src/Tasks/Tasks.csproj
@@ -7,17 +7,21 @@
false
+
+
+
+
- all
- runtime; build; native; contentfiles; analyzers; buildtransitive
+ all
+ runtime; build; native; contentfiles; analyzers; buildtransitive
- all
- runtime; build; native; contentfiles; analyzers; buildtransitive
+ all
+ runtime; build; native; contentfiles; analyzers; buildtransitive
@@ -40,7 +44,7 @@
-
+
$(SolutionDir)/Guidelines/tasks/$(TargetFramework)
@@ -50,4 +54,4 @@
-
+
\ No newline at end of file
diff --git a/src/stylecop.json b/src/stylecop.json
new file mode 100644
index 0000000..78e2de8
--- /dev/null
+++ b/src/stylecop.json
@@ -0,0 +1,18 @@
+{
+ "$schema": "https://raw.githubusercontent.com/DotNetAnalyzers/StyleCopAnalyzers/master/StyleCop.Analyzers/StyleCop.Analyzers/Settings/stylecop.schema.json",
+ "settings": {
+ "indentation": {
+ "indentationSize": 4,
+ "tabSize": 4,
+ "useTabs": false
+ },
+ "orderingRules": {
+ "usingDirectivesPlacement": "outsideNamespace",
+ "blankLinesBetweenUsingGroups": "allow",
+ "systemUsingDirectivesFirst": true
+ },
+ "documentationRules": {
+ "xmlHeader": false
+ }
+ }
+}