├── .editorconfig
├── .gitattributes
├── .gitignore
├── .gitmodules
├── AutoCodeFix.sln
├── CODE_OF_CONDUCT.md
├── LICENSE
├── NuGet.Config
├── README.md
├── azure-build.yml
├── azure-pipelines.yml
├── external
└── Directory.Build.targets
├── icon
├── 32.png
├── 48.png
├── 64.png
├── noun_Gear_2069169.png
├── noun_Gear_2069169.svg
└── readme.md
└── src
├── AutoCodeFix.Package
└── AutoCodeFix.Package.msbuildproj
├── AutoCodeFix.ProjectReader
├── App.config
├── AutoCodeFix.ProjectReader.csproj
├── Empty.csproj
├── Empty.vbproj
└── Program.cs
├── AutoCodeFix.Tasks
├── ApplyCodeFixes.cs
├── AssemblyResolver.cs
├── AutoCodeFix.Core.targets
├── AutoCodeFix.DesignTime.targets
├── AutoCodeFix.Tasks.csproj
├── AutoCodeFix.props
├── AutoCodeFix.targets
├── BuildExtensions.cs
├── BuildWorkspace.cs
├── CollectAutoCodeFixWarnings.cs
├── DisposableAction.cs
├── DocumentExtensions.cs
├── IBuildConfiguration.cs
├── IWorkspace.cs
├── InitializeBuildEnvironment.cs
├── Internals.cs
├── ProjectReader.cs
├── Properties
│ ├── Resources.Designer.cs
│ └── Resources.resx
├── RecordAutoCodeFixWarnings.cs
├── ResolveLocalAssemblies.cs
├── SetAutoCodeFixEnvironment.cs
├── StyleCop
│ ├── CodeFixEquivalenceGroup.cs
│ └── TesterDiagnosticProvider.cs
└── WarningsRecorder.cs
├── AutoCodeFix.Tests
├── AutoCodeFix.Tests.csproj
├── AutoFix.cs
├── AutoFix.feature
├── GherkinatorExtensions.cs
└── Virtualizer.cs
├── Directory.Build.props
├── Directory.Build.targets
├── GitInfo.txt
├── Packages.props
├── Version.targets
└── global.json
/.editorconfig:
--------------------------------------------------------------------------------
1 | # EditorConfig is awesome:http://EditorConfig.org
2 |
3 | # top-most EditorConfig file
4 | root = true
5 |
6 | # Don't use tabs for indentation.
7 | [*]
8 | indent_style = space
9 | # (Please don't specify an indent_size here; that has too many unintended consequences.)
10 |
11 | # Code files
12 | [*.{cs,csx,vb,vbx}]
13 | indent_size = 4
14 |
15 | # Xml project files
16 | [*.{csproj,vbproj,vcxproj,vcxproj.filters,proj,projitems,shproj}]
17 | indent_size = 2
18 |
19 | # Xml config files
20 | [*.{props,targets,ruleset,config,nuspec,resx,vsixmanifest,vsct}]
21 | indent_size = 2
22 |
23 | # Yaml files
24 | [*.yml]
25 | indent_size = 2
26 |
27 | # JSON files
28 | [*.json]
29 | indent_size = 2
30 |
31 | # Dotnet code style settings:
32 | [*.{cs,vb}]
33 | # Sort using and Import directives with System.* appearing first
34 | dotnet_sort_system_directives_first = true
35 | # Avoid "this." and "Me." if not necessary
36 | dotnet_style_qualification_for_field = false:suggestion
37 | dotnet_style_qualification_for_property = false:suggestion
38 | dotnet_style_qualification_for_method = false:suggestion
39 | dotnet_style_qualification_for_event = false:suggestion
40 |
41 | # Use language keywords instead of framework type names for type references
42 | dotnet_style_predefined_type_for_locals_parameters_members = true:suggestion
43 | dotnet_style_predefined_type_for_member_access = true:suggestion
44 |
45 | # Suggest more modern language features when available
46 | dotnet_style_object_initializer = true:suggestion
47 | dotnet_style_collection_initializer = true:suggestion
48 | dotnet_style_coalesce_expression = true:suggestion
49 | dotnet_style_null_propagation = true:suggestion
50 | dotnet_style_explicit_tuple_names = true:suggestion
51 |
52 | # CSharp code style settings:
53 | [*.cs]
54 | # Prefer "var" everywhere
55 | csharp_style_var_for_built_in_types = true:suggestion
56 | csharp_style_var_when_type_is_apparent = true:suggestion
57 | csharp_style_var_elsewhere = true:suggestion
58 |
59 | # Prefer method-like constructs to have a block body
60 | csharp_style_expression_bodied_methods = false:none
61 | csharp_style_expression_bodied_constructors = false:none
62 | csharp_style_expression_bodied_operators = false:none
63 |
64 | # Prefer property-like constructs to have an expression-body
65 | csharp_style_expression_bodied_properties = true:none
66 | csharp_style_expression_bodied_indexers = true:none
67 | csharp_style_expression_bodied_accessors = true:none
68 |
69 | # Suggest more modern language features when available
70 | csharp_style_pattern_matching_over_is_with_cast_check = true:suggestion
71 | csharp_style_pattern_matching_over_as_with_null_check = true:suggestion
72 | csharp_style_inlined_variable_declaration = true:suggestion
73 | csharp_style_throw_expression = true:suggestion
74 | csharp_style_conditional_delegate_call = true:suggestion
75 |
76 | # Newline settings
77 | csharp_new_line_before_open_brace = all
78 | csharp_new_line_before_else = true
79 | csharp_new_line_before_catch = true
80 | csharp_new_line_before_finally = true
81 | csharp_new_line_before_members_in_object_initializers = true
82 | csharp_new_line_before_members_in_anonymous_types = true
83 |
--------------------------------------------------------------------------------
/.gitattributes:
--------------------------------------------------------------------------------
1 | ###############################################################################
2 | # Set default behavior to automatically normalize line endings.
3 | ###############################################################################
4 | * text=auto
5 |
6 | ###############################################################################
7 | # Set default behavior for command prompt diff.
8 | #
9 | # This is need for earlier builds of msysgit that does not have it on by
10 | # default for csharp files.
11 | # Note: This is only used by command line
12 | ###############################################################################
13 | #*.cs diff=csharp
14 |
15 | ###############################################################################
16 | # Set the merge driver for project and solution files
17 | #
18 | # Merging from the command prompt will add diff markers to the files if there
19 | # are conflicts (Merging from VS is not affected by the settings below, in VS
20 | # the diff markers are never inserted). Diff markers may cause the following
21 | # file extensions to fail to load in VS. An alternative would be to treat
22 | # these files as binary and thus will always conflict and require user
23 | # intervention with every merge. To do so, just uncomment the entries below
24 | ###############################################################################
25 | #*.sln merge=binary
26 | #*.csproj merge=binary
27 | #*.vbproj merge=binary
28 | #*.vcxproj merge=binary
29 | #*.vcproj merge=binary
30 | #*.dbproj merge=binary
31 | #*.fsproj merge=binary
32 | #*.lsproj merge=binary
33 | #*.wixproj merge=binary
34 | #*.modelproj merge=binary
35 | #*.sqlproj merge=binary
36 | #*.wwaproj merge=binary
37 |
38 | ###############################################################################
39 | # behavior for image files
40 | #
41 | # image files are treated as binary by default.
42 | ###############################################################################
43 | #*.jpg binary
44 | #*.png binary
45 | #*.gif binary
46 |
47 | ###############################################################################
48 | # diff behavior for common document formats
49 | #
50 | # Convert binary document formats to text before diffing them. This feature
51 | # is only available from the command line. Turn it on by uncommenting the
52 | # entries below.
53 | ###############################################################################
54 | #*.doc diff=astextplain
55 | #*.DOC diff=astextplain
56 | #*.docx diff=astextplain
57 | #*.DOCX diff=astextplain
58 | #*.dot diff=astextplain
59 | #*.DOT diff=astextplain
60 | #*.pdf diff=astextplain
61 | #*.PDF diff=astextplain
62 | #*.rtf diff=astextplain
63 | #*.RTF diff=astextplain
64 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | .nuget
2 | .vs
3 | .idea
4 | out
5 | bin
6 | obj
7 | *.nupkg
8 | *.lock.json
9 | *.nuget.props
10 | *.nuget.targets
11 | *.suo
12 | *.user
13 | *.cache
14 | *.log
15 | *.binlog
16 | *.rsp
--------------------------------------------------------------------------------
/.gitmodules:
--------------------------------------------------------------------------------
1 | [submodule "external/Gherkinator"]
2 | path = external/Gherkinator
3 | url = https://github.com/kzu/Gherkinator.git
4 | branch = master
--------------------------------------------------------------------------------
/AutoCodeFix.sln:
--------------------------------------------------------------------------------
1 |
2 | Microsoft Visual Studio Solution File, Format Version 12.00
3 | # Visual Studio Version 16
4 | VisualStudioVersion = 16.0.28417.167
5 | MinimumVisualStudioVersion = 10.0.40219.1
6 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "AutoCodeFix.ProjectReader", "src\AutoCodeFix.ProjectReader\AutoCodeFix.ProjectReader.csproj", "{B83184E2-5D3E-48BA-AC9E-0A1EF131A108}"
7 | EndProject
8 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "AutoCodeFix.Tasks", "src\AutoCodeFix.Tasks\AutoCodeFix.Tasks.csproj", "{135CD01C-AC26-4FA4-99AD-B490AFA8B062}"
9 | EndProject
10 | Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{3836DA4E-9300-4587-8C82-0399EB7350D1}"
11 | ProjectSection(SolutionItems) = preProject
12 | azure-build.yml = azure-build.yml
13 | azure-pipelines.yml = azure-pipelines.yml
14 | src\Directory.Build.props = src\Directory.Build.props
15 | src\Directory.Build.targets = src\Directory.Build.targets
16 | src\global.json = src\global.json
17 | NuGet.Config = NuGet.Config
18 | src\Packages.props = src\Packages.props
19 | README.md = README.md
20 | src\Version.targets = src\Version.targets
21 | EndProjectSection
22 | EndProject
23 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "AutoCodeFix.Tests", "src\AutoCodeFix.Tests\AutoCodeFix.Tests.csproj", "{7B3F4E2F-3B9D-46B3-A3E8-46194CC61B73}"
24 | EndProject
25 | Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Gherkinator", "Gherkinator", "{45AD3328-A714-4CE9-B47D-7097D7676283}"
26 | ProjectSection(SolutionItems) = preProject
27 | external\Gherkinator\src\Directory.Build.props = external\Gherkinator\src\Directory.Build.props
28 | external\Gherkinator\src\Directory.Build.targets = external\Gherkinator\src\Directory.Build.targets
29 | EndProjectSection
30 | EndProject
31 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Gherkinator", "external\Gherkinator\src\Gherkinator\Gherkinator.csproj", "{C4E88EF7-9B83-40C0-B085-90D18FF3A7D8}"
32 | EndProject
33 | Project("{13B669BE-BB05-4DDF-9536-439F39A36129}") = "AutoCodeFix.Package", "src\AutoCodeFix.Package\AutoCodeFix.Package.msbuildproj", "{13956D6F-A714-4E60-9D17-656ADC02C851}"
34 | EndProject
35 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Gherkinator.Build", "external\Gherkinator\src\Gherkinator.Build\Gherkinator.Build.csproj", "{53E3D3A1-E86F-45FE-B06E-5D10EBE589E9}"
36 | EndProject
37 | Global
38 | GlobalSection(SolutionConfigurationPlatforms) = preSolution
39 | Debug|Any CPU = Debug|Any CPU
40 | Release|Any CPU = Release|Any CPU
41 | EndGlobalSection
42 | GlobalSection(ProjectConfigurationPlatforms) = postSolution
43 | {B83184E2-5D3E-48BA-AC9E-0A1EF131A108}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
44 | {B83184E2-5D3E-48BA-AC9E-0A1EF131A108}.Debug|Any CPU.Build.0 = Debug|Any CPU
45 | {B83184E2-5D3E-48BA-AC9E-0A1EF131A108}.Release|Any CPU.ActiveCfg = Release|Any CPU
46 | {B83184E2-5D3E-48BA-AC9E-0A1EF131A108}.Release|Any CPU.Build.0 = Release|Any CPU
47 | {135CD01C-AC26-4FA4-99AD-B490AFA8B062}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
48 | {135CD01C-AC26-4FA4-99AD-B490AFA8B062}.Debug|Any CPU.Build.0 = Debug|Any CPU
49 | {135CD01C-AC26-4FA4-99AD-B490AFA8B062}.Release|Any CPU.ActiveCfg = Release|Any CPU
50 | {135CD01C-AC26-4FA4-99AD-B490AFA8B062}.Release|Any CPU.Build.0 = Release|Any CPU
51 | {7B3F4E2F-3B9D-46B3-A3E8-46194CC61B73}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
52 | {7B3F4E2F-3B9D-46B3-A3E8-46194CC61B73}.Debug|Any CPU.Build.0 = Debug|Any CPU
53 | {7B3F4E2F-3B9D-46B3-A3E8-46194CC61B73}.Release|Any CPU.ActiveCfg = Release|Any CPU
54 | {7B3F4E2F-3B9D-46B3-A3E8-46194CC61B73}.Release|Any CPU.Build.0 = Release|Any CPU
55 | {C4E88EF7-9B83-40C0-B085-90D18FF3A7D8}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
56 | {C4E88EF7-9B83-40C0-B085-90D18FF3A7D8}.Debug|Any CPU.Build.0 = Debug|Any CPU
57 | {C4E88EF7-9B83-40C0-B085-90D18FF3A7D8}.Release|Any CPU.ActiveCfg = Release|Any CPU
58 | {C4E88EF7-9B83-40C0-B085-90D18FF3A7D8}.Release|Any CPU.Build.0 = Release|Any CPU
59 | {13956D6F-A714-4E60-9D17-656ADC02C851}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
60 | {13956D6F-A714-4E60-9D17-656ADC02C851}.Debug|Any CPU.Build.0 = Debug|Any CPU
61 | {13956D6F-A714-4E60-9D17-656ADC02C851}.Release|Any CPU.ActiveCfg = Release|Any CPU
62 | {13956D6F-A714-4E60-9D17-656ADC02C851}.Release|Any CPU.Build.0 = Release|Any CPU
63 | {53E3D3A1-E86F-45FE-B06E-5D10EBE589E9}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
64 | {53E3D3A1-E86F-45FE-B06E-5D10EBE589E9}.Debug|Any CPU.Build.0 = Debug|Any CPU
65 | {53E3D3A1-E86F-45FE-B06E-5D10EBE589E9}.Release|Any CPU.ActiveCfg = Release|Any CPU
66 | {53E3D3A1-E86F-45FE-B06E-5D10EBE589E9}.Release|Any CPU.Build.0 = Release|Any CPU
67 | EndGlobalSection
68 | GlobalSection(SolutionProperties) = preSolution
69 | HideSolutionNode = FALSE
70 | EndGlobalSection
71 | GlobalSection(NestedProjects) = preSolution
72 | {C4E88EF7-9B83-40C0-B085-90D18FF3A7D8} = {45AD3328-A714-4CE9-B47D-7097D7676283}
73 | {53E3D3A1-E86F-45FE-B06E-5D10EBE589E9} = {45AD3328-A714-4CE9-B47D-7097D7676283}
74 | EndGlobalSection
75 | GlobalSection(ExtensibilityGlobals) = postSolution
76 | SolutionGuid = {0D057138-81AC-4232-B280-867A24BA4E13}
77 | EndGlobalSection
78 | EndGlobal
79 |
--------------------------------------------------------------------------------
/CODE_OF_CONDUCT.md:
--------------------------------------------------------------------------------
1 | # Contributor Covenant Code of Conduct
2 |
3 | ## Our Pledge
4 |
5 | In the interest of fostering an open and welcoming environment, we as contributors and maintainers pledge to making participation in our project and our community a harassment-free experience for everyone, regardless of age, body size, disability, ethnicity, gender identity and expression, level of experience, nationality, personal appearance, race, religion, or sexual identity and orientation.
6 |
7 | ## Our Standards
8 |
9 | Examples of behavior that contributes to creating a positive environment include:
10 |
11 | * Using welcoming and inclusive language
12 | * Being respectful of differing viewpoints and experiences
13 | * Gracefully accepting constructive criticism
14 | * Focusing on what is best for the community
15 | * Showing empathy towards other community members
16 |
17 | Examples of unacceptable behavior by participants include:
18 |
19 | * The use of sexualized language or imagery and unwelcome sexual attention or advances
20 | * Trolling, insulting/derogatory comments, and personal or political attacks
21 | * Public or private harassment
22 | * Publishing others' private information, such as a physical or electronic address, without explicit permission
23 | * Other conduct which could reasonably be considered inappropriate in a professional setting
24 |
25 | ## Our Responsibilities
26 |
27 | Project maintainers are responsible for clarifying the standards of acceptable behavior and are expected to take appropriate and fair corrective action in response to any instances of unacceptable behavior.
28 |
29 | Project maintainers have the right and responsibility to remove, edit, or reject comments, commits, code, wiki edits, issues, and other contributions that are not aligned to this Code of Conduct, or to ban temporarily or permanently any contributor for other behaviors that they deem inappropriate, threatening, offensive, or harmful.
30 |
31 | ## Scope
32 |
33 | This Code of Conduct applies both within project spaces and in public spaces when an individual is representing the project or its community. Examples of representing a project or community include using an official project e-mail address, posting via an official social media account, or acting as an appointed representative at an online or offline event. Representation of a project may be further defined and clarified by project maintainers.
34 |
35 | ## Enforcement
36 |
37 | Instances of abusive, harassing, or otherwise unacceptable behavior may be reported by contacting the project team at daniel@cazzulino.com. The project team will review and investigate all complaints, and will respond in a way that it deems appropriate to the circumstances. The project team is obligated to maintain confidentiality with regard to the reporter of an incident. Further details of specific enforcement policies may be posted separately.
38 |
39 | Project maintainers who do not follow or enforce the Code of Conduct in good faith may face temporary or permanent repercussions as determined by other members of the project's leadership.
40 |
41 | ## Attribution
42 |
43 | This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4, available at [http://contributor-covenant.org/version/1/4][version]
44 |
45 | [homepage]: http://contributor-covenant.org
46 | [version]: http://contributor-covenant.org/version/1/4/
47 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2018 Daniel Cazzulino
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/NuGet.Config:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 |  AutoCodeFix
2 | ============
3 |
4 | [](https://www.nuget.org/packages/AutoCodeFix)
5 | [](https://www.nuget.org/packages/AutoCodeFix)
6 | [](http://build.azdo.io/kzu/oss/19)
7 |
8 | Applies Roslyn code fixes automatically during build for the chosen "auto codefix" diagnostics, fixing
9 | the code for you automatically, instead of having to manually apply code fixes in the IDE.
10 |
11 | In the project file, specify the diagnostic identifiers you want to apply code fixes automatically to.
12 | This example uses two diagnostics from the [StyleCop.Analyzers](https://www.nuget.org/packages/StyleCop.Analyzers)
13 | package:
14 |
15 | ```xml
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 | ```
28 |
29 | The analyzers and code fixes available during build are the same used during design time in the
30 | IDE, added to the project via the `` item group. Analyzers
31 | distributed via nuget packages already add those automatically to your project (such as the
32 | [StyleCop.Analyzers](https://www.nuget.org/packages/StyleCop.Analyzers) ,
33 | [RefactoringEssentials](https://www.nuget.org/packages/RefactoringEssentials),
34 | [Roslynator.Analyzers](https://www.nuget.org/packages/Roslynator.Analyzers) and
35 | [Roslynator.CodeFixes](https://www.nuget.org/Roslynator.CodeFixes), etc).
36 |
37 | It's important to note that by default, the compiler *has* to emit the diagnostics you want them
38 | fixed automatically. For diagnostics that are of `Info` severity by default (i.e. [RCS1003: Add braces to if-else](https://github.com/JosefPihrt/Roslynator/blob/master/docs/analyzers/RCS1003.md))
39 | you can bump its severity to `Warning` so that `AutoCodeFix` can properly process them automatically on the next build.
40 |
41 | You [configure analyzers](https://docs.microsoft.com/en-us/visualstudio/code-quality/use-roslyn-analyzers?view=vs-2017) using
42 | the built-in editor in VS, which for the example above, would result in a rule set like the following:
43 |
44 | ```xml
45 |
46 |
47 |
48 |
49 |
50 | ```
51 |
52 | With that configuration in place, you can add the `AutoCodeFix` just like before:
53 |
54 | ```xml
55 |
56 |
57 |
58 | ```
59 |
60 | When no fixable diagnostics are emitted by the compiler, the impact of `AutoCodeFix` on build times
61 | is virtually none.
62 |
63 |
64 | > NOTE: the main use case for `AutoCodeFix` is to fix the code as you go, on every build. Therefore, it performs
65 | > best when warnings to fix are few and introduced in between builds. Although it can be used to apply fixes to
66 | > entire code bases for normalization/compliance purposes as a one-time fixup, that can take some time, even if
67 | > a [Fix All](https://github.com/dotnet/roslyn/blob/master/docs/analyzers/FixAllProvider.md) provider exists
68 | > for the diagnostics. Run time is also impacted by the complexity of the code fix itself. As an example,
69 | > the StyleCop code fix for [usings sorting](https://github.com/DotNetAnalyzers/StyleCopAnalyzers/blob/master/documentation/SA1208.md)
70 | > can fix ~60 instances per second on my Dell XPS 13 9370.
71 |
72 |
73 | > Icon [Gear](https://thenounproject.com/term/gear/2069169/) by
74 | > [Putra Theoo](https://thenounproject.com/tnputra555),
75 | > from [The Noun Project](https://thenounproject.com/)
76 |
--------------------------------------------------------------------------------
/azure-build.yml:
--------------------------------------------------------------------------------
1 | # Builds and tests AutoCodeFix for the specified
2 | # versions of Roslyn
3 |
4 | parameters:
5 | roslyn: ''
6 |
7 | steps:
8 | - task: MSBuild@1
9 | displayName: Restore ${{ parameters.roslyn }}
10 | inputs:
11 | solution: AutoCodeFix.sln
12 | configuration: $(Configuration)
13 | msbuildArguments: -t:restore -p:RoslynVersion=${{ parameters.roslyn }}
14 |
15 | - task: MSBuild@1
16 | displayName: Build ${{ parameters.roslyn }}
17 | inputs:
18 | solution: AutoCodeFix.sln
19 | configuration: $(Configuration)
20 | msbuildArguments: -p:GeneratePackageOnBuild=true -p:RoslynVersion=${{ parameters.roslyn }} -p:PackageOutputPath=$(Build.ArtifactStagingDirectory)/pkgs -bl:"$(Build.ArtifactStagingDirectory)/logs/build.${{ parameters.roslyn }}.binlog"
21 |
22 | - task: VSTest@2
23 | displayName: Test ${{ parameters.roslyn }}
24 | timeoutInMinutes: 5
25 | inputs:
26 | testAssemblyVer2: src/AutoCodeFix.Tests/bin/*/AutoCodeFix.Tests.dll
27 | runInParallel: true
28 | codeCoverageEnabled: true
29 | publishRunAttachments: true
30 | diagnosticsEnabled: false
31 | rerunFailedTests: true
32 |
33 | - task: PublishBuildArtifacts@1
34 | displayName: Upload Packages
35 | condition: succeeded()
36 | inputs:
37 | PathtoPublish: $(Build.ArtifactStagingDirectory)/pkgs
38 | ArtifactName: packages
39 | ArtifactType: Container
40 |
41 | - task: PublishBuildArtifacts@1
42 | displayName: Upload Logs
43 | condition: always()
44 | inputs:
45 | PathtoPublish: $(Build.ArtifactStagingDirectory)/logs
46 | ArtifactName: logs
47 | ArtifactType: Container
48 |
--------------------------------------------------------------------------------
/azure-pipelines.yml:
--------------------------------------------------------------------------------
1 | trigger:
2 | batch: false
3 | branches:
4 | include:
5 | - master
6 | - features/*
7 | - releases/*
8 | - dev/*
9 | paths:
10 | exclude:
11 | - docs
12 | pr:
13 | - master
14 | - features/*
15 | - releases/*
16 |
17 | variables:
18 | - group: Sleet
19 | - name: Configuration
20 | value: Release
21 | - name: ReleaseLabel
22 | value: beta
23 |
24 | stages:
25 |
26 | - stage: Build2017
27 | dependsOn: []
28 | jobs:
29 | - job: Build
30 | pool:
31 | vmImage: 'windows-2019'
32 | steps:
33 | - checkout: self
34 | clean: true
35 |
36 | - template: azure-build.yml
37 | parameters:
38 | roslyn: '2.10.0'
39 |
40 | - stage: Build2019_3_0
41 | dependsOn: []
42 | jobs:
43 | - job: Build
44 | pool:
45 | vmImage: 'windows-2019'
46 | steps:
47 | - checkout: self
48 | clean: true
49 |
50 | - template: azure-build.yml
51 | parameters:
52 | roslyn: '3.0.0'
53 |
54 | - stage: Build2019_3_1
55 | dependsOn: []
56 | jobs:
57 | - job: Build
58 | pool:
59 | vmImage: 'windows-2019'
60 | steps:
61 | - checkout: self
62 | clean: true
63 |
64 | - template: azure-build.yml
65 | parameters:
66 | roslyn: '3.1.0'
67 |
68 | - stage: Deploy
69 | dependsOn:
70 | - Build2017
71 | - Build2019_3_0
72 | - Build2019_3_1
73 | variables:
74 | - name: SleetVersion
75 | value: 2.3.33
76 | jobs:
77 | - deployment: Deploy
78 | pool:
79 | vmImage: 'windows-2019'
80 | environment: sleet
81 | strategy:
82 | runOnce:
83 | deploy:
84 | steps:
85 | - pwsh: |
86 | $anyinstalled = (dotnet tool list -g | select-string sleet) -ne $null
87 | Write-Host "##vso[task.setvariable variable=Sleet.AnyInstalled;]$anyinstalled"
88 |
89 | $sameinstalled = (dotnet tool list -g | select-string sleet | select-string $(SleetVersion)) -ne $null
90 | Write-Host "##vso[task.setvariable variable=Sleet.SameInstalled;]$sameinstalled"
91 | displayName: 'Check Sleet installed version'
92 |
93 | - task: DotNetCoreCLI@2
94 | displayName: 'Uninstall Sleet if necessary'
95 | continueOnError: true
96 | condition: and(eq(variables['Sleet.AnyInstalled'], 'True'), eq(variables['Sleet.SameInstalled'], 'False'))
97 | inputs:
98 | command: custom
99 | custom: tool
100 | arguments: 'uninstall -g Sleet'
101 |
102 | - task: DotNetCoreCLI@2
103 | displayName: 'Install Sleet if necessary'
104 | condition: eq(variables['Sleet.SameInstalled'], 'False')
105 | inputs:
106 | command: custom
107 | custom: tool
108 | arguments: 'install --global Sleet --version $(SleetVersion)'
109 |
110 | - task: DownloadPipelineArtifact@2
111 | inputs:
112 | artifactName: packages
113 |
114 | - script: 'sleet push --config none $(Pipeline.Workspace)/packages -f --verbose -p "SLEET_FEED_CONNECTIONSTRING=$(SLEET_FEED_CONNECTIONSTRING)"'
115 | displayName: 'Push package via Sleet'
--------------------------------------------------------------------------------
/external/Directory.Build.targets:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | false
5 | false
6 |
7 |
8 |
--------------------------------------------------------------------------------
/icon/32.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kzu/AutoCodeFix/50aace00922eb35d89bcdc77ef83da50e06fd50c/icon/32.png
--------------------------------------------------------------------------------
/icon/48.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kzu/AutoCodeFix/50aace00922eb35d89bcdc77ef83da50e06fd50c/icon/48.png
--------------------------------------------------------------------------------
/icon/64.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kzu/AutoCodeFix/50aace00922eb35d89bcdc77ef83da50e06fd50c/icon/64.png
--------------------------------------------------------------------------------
/icon/noun_Gear_2069169.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kzu/AutoCodeFix/50aace00922eb35d89bcdc77ef83da50e06fd50c/icon/noun_Gear_2069169.png
--------------------------------------------------------------------------------
/icon/noun_Gear_2069169.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/icon/readme.md:
--------------------------------------------------------------------------------
1 | [Gear](https://thenounproject.com/term/gear/2069169/) by
2 | [Putra Theoo](https://thenounproject.com/tnputra555),
3 | from [The Noun Project](https://thenounproject.com/)
--------------------------------------------------------------------------------
/src/AutoCodeFix.Package/AutoCodeFix.Package.msbuildproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | net472
6 |
7 |
8 |
9 | AutoCodeFix
10 | Applies code fixes automatically during build.
11 | AutoCodeFix
12 | https://raw.github.com/kzu/AutoCodeFix/master/icon/64.png
13 | https://github.com/kzu/AutoCodeFix
14 | MIT
15 | https://raw.githubusercontent.com/kzu/AutoCodeFix/master/LICENSE
16 | roslyn codegen codefix analyzer
17 |
18 |
19 |
20 | true
21 | false
22 | false
23 | PackageReference
24 | NO-SDK-PACK
25 | true
26 | false
27 | false
28 | true
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 | <_ToDelete Include="$(TEMP)\packages\$(PackageId)*.nupkg" />
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
--------------------------------------------------------------------------------
/src/AutoCodeFix.ProjectReader/App.config:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
11 |
12 |
13 |
14 |
15 |
--------------------------------------------------------------------------------
/src/AutoCodeFix.ProjectReader/AutoCodeFix.ProjectReader.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | ProjectReader
6 | AutoCodeFix
7 | Exe
8 | false
9 |
10 | tools
11 | false
12 | false
13 | true
14 | true
15 |
16 | net472
17 | net46
18 |
19 |
20 |
21 |
22 | all
23 | false
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 |
--------------------------------------------------------------------------------
/src/AutoCodeFix.ProjectReader/Empty.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 | netstandard2.0
4 |
5 |
6 |
--------------------------------------------------------------------------------
/src/AutoCodeFix.ProjectReader/Empty.vbproj:
--------------------------------------------------------------------------------
1 |
2 |
3 | netstandard2.0
4 |
5 |
6 |
--------------------------------------------------------------------------------
/src/AutoCodeFix.ProjectReader/Program.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Diagnostics;
4 | using System.Dynamic;
5 | using System.IO;
6 | using System.Linq;
7 | using System.Reflection;
8 | using System.Threading;
9 | using System.Threading.Tasks;
10 | using Microsoft.Build.Locator;
11 | using Microsoft.CodeAnalysis;
12 | using Microsoft.CodeAnalysis.MSBuild;
13 | using Mono.Options;
14 | using Newtonsoft.Json;
15 | using StreamJsonRpc;
16 |
17 | namespace AutoCodeFix
18 | {
19 | internal class Program
20 | {
21 | private static readonly TraceSource tracer = new TraceSource(nameof(AutoCodeFix));
22 | private static ManualResetEventSlim exit = new ManualResetEventSlim();
23 | private static bool ready;
24 | private static Task initializer = Task.CompletedTask;
25 |
26 | public static async Task Main(string[] args)
27 | {
28 | var help = false;
29 | var msbuild = default(string);
30 | var wait = false;
31 | var parent = default(Process);
32 | var project = default(string);
33 | var properties = new Dictionary();
34 | var output = default(string);
35 | var parentId = 0;
36 | var parentNotFound = false;
37 |
38 | var options = new OptionSet
39 | {
40 | { "m|msbuild=", "MSBuild root directory.", m => msbuild = m },
41 | { "p|project:", "MSBuild project file to read", s => project = s },
42 | { "o|output:", "Output file to emit. Emits to standard output if not specified", o => output = o },
43 | { "<>", "Additional MSBuild global properties to set", v =>
44 | {
45 | var values = v.Split(new[] { '=', ':' }, 2);
46 | properties[values[0].Trim()] = values[1].Trim().Trim('\"');
47 | }
48 | },
49 | new ResponseFileSource(),
50 | { "parent:", "Parent process ID to monitor to automatically exit", (int p) =>
51 | {
52 | try
53 | {
54 | parentId = p;
55 | parent = Process.GetProcessById(p);
56 | }
57 | catch (ArgumentException)
58 | {
59 | parentNotFound = true;
60 | }
61 | }
62 | },
63 | { "w|wait", "Wait before exiting when a source project or solution is specified", w => wait = true },
64 | { "d|debug", "Attach a debugger to the process", d => Debugger.Launch() },
65 | { "h|?|help", "Show this message and exit", h => help = true },
66 | };
67 |
68 | List extra;
69 | var appName = Path.GetFileName(Assembly.GetExecutingAssembly().ManifestModule.FullyQualifiedName);
70 |
71 | try
72 | {
73 | extra = options.Parse(args);
74 | if (parentNotFound)
75 | {
76 | Console.Error.WriteLine($"Specified parent process ID {parentId} is not running. Exiting.");
77 | return -1;
78 | }
79 |
80 | if (help || string.IsNullOrEmpty(msbuild))
81 | {
82 | var writer = help ? Console.Out : Console.Error;
83 |
84 | // show some app description message
85 | writer.WriteLine($"Usage: {appName} [OPTIONS]+");
86 | writer.WriteLine();
87 |
88 | writer.WriteLine("Options:");
89 | options.WriteOptionDescriptions(writer);
90 |
91 | return -1;
92 | }
93 |
94 | MSBuildLocator.RegisterMSBuildPath(msbuild);
95 |
96 | if (parent != null)
97 | {
98 | if (parent.HasExited)
99 | return 0;
100 |
101 | parent.EnableRaisingEvents = true;
102 | parent.Exited += (_, __) => exit.Set();
103 | }
104 |
105 | if (!string.IsNullOrEmpty(project))
106 | {
107 | // The intent is to operate in standalone commandline,
108 | // so no JsonRpc will be set up.
109 | var program = new Program();
110 |
111 | if (properties.Count == 0)
112 | Console.WriteLine($@"Creating workspace...");
113 | else
114 | Console.WriteLine($@"Creating workspace with properties:
115 | {properties.Select(pair => $"\t{pair.Key}={pair.Value}")}");
116 |
117 | await program.CreateWorkspaceAsync(properties);
118 | Console.WriteLine($@"Opening project {Path.GetFileName(project)}...");
119 | var metadata = await program.OpenProjectAsync(project);
120 | if (string.IsNullOrEmpty(output))
121 | Console.WriteLine(JsonConvert.SerializeObject(metadata, Formatting.Indented, new EnumConverter()));
122 | else
123 | File.WriteAllText(output, JsonConvert.SerializeObject(metadata, Formatting.Indented, new EnumConverter()));
124 |
125 | Console.WriteLine("Done");
126 |
127 | if (wait)
128 | Console.ReadLine();
129 |
130 | return 0;
131 | }
132 | else
133 | {
134 | // When no source is passed in, we assume the mode will be RPC and start
135 | // listening
136 | var program = new Program();
137 | var rpc = new JsonRpc(Console.OpenStandardOutput(), Console.OpenStandardInput(), program);
138 | rpc.StartListening();
139 |
140 | // Force resolving right-away.
141 | initializer = Task.Run(Init);
142 | exit.Wait();
143 |
144 | program.workspace?.Dispose();
145 |
146 | return 0;
147 | }
148 | }
149 | catch (OptionException e)
150 | {
151 | Console.Error.WriteLine($"{appName}: {e.Message}");
152 | Console.Error.WriteLine($"Try '{appName} -?' for more information.");
153 |
154 | if (wait)
155 | {
156 | Console.ReadLine();
157 | }
158 |
159 | return -1;
160 | }
161 | catch (ReflectionTypeLoadException re)
162 | {
163 | #if DEBUG
164 | if (!Debugger.IsAttached)
165 | {
166 | Debugger.Launch();
167 | }
168 | #endif
169 |
170 | // TODO: should we render something different in this case? (non-options exception?)
171 | Console.Error.WriteLine($"{appName}: {string.Join(Environment.NewLine, re.LoaderExceptions.Select(e => e.ToString()))}");
172 |
173 | if (wait)
174 | {
175 | Console.ReadLine();
176 | }
177 |
178 | return -1;
179 | }
180 | catch (Exception e)
181 | {
182 | #if DEBUG
183 | if (!Debugger.IsAttached)
184 | {
185 | Debugger.Launch();
186 | }
187 | #endif
188 |
189 | // TODO: should we render something different in this case? (non-options exception?)
190 | Console.Error.WriteLine($"{appName}: {e.Message}");
191 |
192 | if (wait)
193 | {
194 | Console.ReadLine();
195 | }
196 |
197 | return -1;
198 | }
199 | }
200 |
201 | private static async Task Init()
202 | {
203 | var workspace = MSBuildWorkspace.Create();
204 | await workspace.OpenProjectAsync(
205 | Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().ManifestModule.FullyQualifiedName), "Empty.csproj"));
206 | await workspace.OpenProjectAsync(
207 | Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().ManifestModule.FullyQualifiedName), "Empty.vbproj"));
208 | ready = true;
209 | }
210 |
211 | private MSBuildWorkspace workspace;
212 |
213 | public void Debug() => Debugger.Launch();
214 |
215 | public void Exit() => Task.Delay(200).ContinueWith(_ => exit.Set());
216 |
217 | public bool Ping() => ready;
218 |
219 | public async Task CreateWorkspaceAsync(Dictionary properties)
220 | {
221 | await initializer;
222 | workspace?.Dispose();
223 | try
224 | {
225 | workspace = MSBuildWorkspace.Create(properties);
226 | workspace.WorkspaceFailed += (sender, args) => tracer.TraceEvent(TraceEventType.Error, 0, $"{args.Diagnostic.Kind}: {args.Diagnostic.Message}");
227 | workspace.SkipUnrecognizedProjects = true;
228 | }
229 | catch (Exception e)
230 | {
231 | tracer.TraceEvent(TraceEventType.Error, 0, e.ToString());
232 | throw;
233 | }
234 | }
235 |
236 | public async Task CloseWorkspaceAsync()
237 | {
238 | await initializer;
239 | workspace?.Dispose();
240 | }
241 |
242 | public async Task