Code Monkey home page Code Monkey logo

realvizu / nsdepcop Goto Github PK

View Code? Open in Web Editor NEW
181.0 13.0 28.0 17.09 MB

NsDepCop is a static code analysis tool that helps to enforce namespace dependency rules in C# projects. No more unplanned or unnoticed dependencies in your system.

License: GNU General Public License v2.0

C# 89.81% Batchfile 0.21% Smalltalk 0.12% PowerShell 9.86%
dependency-analysis csharp static-code-analysis msbuild visual-studio-extension namespace dependencies dotnet nuget

nsdepcop's People

Contributors

mcintyre321 avatar mgoutrie avatar pragone avatar realvizu avatar stevedunn avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

nsdepcop's Issues

Temp .cs file not found, analyser throws exception

Happens on projects that contain MS workflow designer.
Confirmed that the temp .cs file really does not exist on the given path (so not a permission problem).

Snippet from the build output:

26>MSBUILD : error NSDEPCOPEX: [NsDepCop] System.IO.FileNotFoundException: Could not find file 'C:\Users\ferenc.vizkeleti\AppData\Local\Temp\ku41wvbl.cs'.
26>MSBUILD : error NSDEPCOPEX: File name: 'C:\Users\ferenc.vizkeleti\AppData\Local\Temp\ku41wvbl.cs'
26>MSBUILD : error NSDEPCOPEX:    at System.IO.__Error.WinIOError(Int32 errorCode, String maybeFullPath)
26>MSBUILD : error NSDEPCOPEX:    at System.IO.FileStream.Init(String path, FileMode mode, FileAccess access, Int32 rights, Boolean useRights, FileShare share, Int32 bufferSize, FileOptions options, SECURITY_ATTRIBUTES secAttrs, String msgPath, Boolean bFromProxy, Boolean useLongPath, Boolean checkHost)
26>MSBUILD : error NSDEPCOPEX:    at System.IO.FileStream..ctor(String path, FileMode mode, FileAccess access, FileShare share)
26>MSBUILD : error NSDEPCOPEX:    at Microsoft.CodeAnalysis.CSharp.CSharpSyntaxTree.ParseFile(String path, CSharpParseOptions options, CancellationToken cancellationToken)
26>MSBUILD : error NSDEPCOPEX:    at Codartis.NsDepCop.Core.Analyzer.Roslyn.DependencyAnalyzer.<AnalyzeProject>b__2(String i)
26>MSBUILD : error NSDEPCOPEX:    at System.Linq.Enumerable.<>c__DisplayClass7_0`3.<CombineSelectors>b__0(TSource x)
26>MSBUILD : error NSDEPCOPEX:    at System.Linq.Enumerable.WhereSelectListIterator`2.MoveNext()
26>MSBUILD : error NSDEPCOPEX:    at System.Collections.Generic.List`1..ctor(IEnumerable`1 collection)
26>MSBUILD : error NSDEPCOPEX:    at System.Linq.Enumerable.ToList[TSource](IEnumerable`1 source)
26>MSBUILD : error NSDEPCOPEX:    at Codartis.NsDepCop.Core.Analyzer.Roslyn.DependencyAnalyzer.<AnalyzeProject>d__4.MoveNext()
26>MSBUILD : error NSDEPCOPEX:    at Codartis.NsDepCop.MsBuildTask.NsDepCopTask.Execute()

Disallowed from a.* to a.b.* causes a.b.c->a.b.c to throw a warning

ChildCanDependOnParentImplicitly="true" and

Will cause any references between the Core.Something.SubSomething namespace (and it's children) to Core.Something.SubSomething.* namespaces to throw an illegal namespace warning.

And also, Core.Something.SubSomething.Things1 namespace should be able to reference Core.Something.SubSomething.Thing2 namespace without issue. but a lateral reference is not allowed. and since Disallowed is stronger than Allowed, the lateral movement is reported as an illegal reference.

Incremental build not triggered when only config.nsdepcop have changed

  1. Build a csproj
  2. Modify and save config.nsdepcop
  3. Build again

Expected: NsDepCop analysis is executed.
Actual: Nothing happens, no build is triggered.

This happens only in VS and with the new project system.

If msbuild is started directly (from cmd prompt) it works as expected (NsDepCop is executed).
If the project file has the legacy format then it works as expected too.

Create perf tests with BenckmarkDotNet

Create perf tests with BecnhmarkDotNet that we can use to detect performance degradation when implementing new features.

Questions:

  • What should be the subject of the benchmarks?
    • A real-life codebase would be preferred to some synthetic (generated) test subject. Also, it should be stable, eg. a concrete version of a project on GitHub?
    • Eg. a concrete former version of NsDepCop itself?
  • What would be the benchmarking process?
    • I guess only those benchmars can be compared that were executed on the same machine. So if someone implements a new feature that is a potential perf. hit, then he should execute a benchmark with and without the new feature?

Solve performance problem caused by NsDepCopTask being an AppDomainIsolatedTask

In v1.7 NsDepCopTask's base class was changed from Task to AppDomainIsolatedTask to avoid some esoteric exceptions caused by assembly version clashing with other tasks (see #25).

The downside of this changes is that AppDomainIsolatedTasks are not reused so AppDomain creation, assembly loading and jitting occures every time NsDepCopTask is invoked resulting in a severe performance hit.

So NsDepCopTask should be changed back to derive from Task when possible (when assembly version redirection is no longer needed).

NsDepCopDiagnosticAnalyzer should write diagnostic trace info to Visual Studio Activity Log

At the moment NsDepCopDiagnosticAnalyzer writes its own diagnostic trace messages (eg. cache hits/misses) to the debug output and it works in the debug build only.

It would be better if it could be configured on the host whether diagnostic trace messages are emitted or not. In case of Visual Studio being the host the obvious mechanism for writing diagnostic trace messages would be the Visual Studio Activity Log. The problem is that NsDepCopDiagnosticAnalyzer is a DiagnosticAnalyzer descendant and not a VSPackage so I can't obtain the IVsActivityLog service from the host.

MissingMethodException: MetadataReader.GetBlobContent

Exception in NsDepCopTask:

System.MissingMethodException: „System.Collections.Immutable.ImmutableArray`1 System.Reflection.Metadata.MetadataReader.GetBlobContent(System.Reflection.Metadata.BlobHandle)”.
at: Microsoft.CodeAnalysis.MetadataReaderExtensions.CreateAssemblyIdentityOrThrow(MetadataReader reader, Version version, AssemblyFlags flags, BlobHandle publicKey, StringHandle name, StringHandle culture, Boolean isReference)
...

Microsoft (R) Build Engine version 15.1.1012.6693
Happens only when msbuild runs in parallel mode (/m).

Checked the loaded modules in VS debugger and the correct version of System.Reflection.Metadata is loaded (1.2.1.0, 4.6.24816.1) and the GetBlobContent method is definitely not missing.

Types referenced in attribute arguments are not detected for attributes on enum values

When a type is referenced from the arguments of an attribute, and this attribute is placed on an enum field, violations are not detected.

In the example below the attribute type is defined in the local namespace, but the types ForbiddenType and ForbiddenAttribute are defined in some namespace that is disallowed in the NsDepCop config.
The use of the forbidden type is detected correctly except in the fifth example, where it is not detected. It appears to be missed only when it is placed on a field (value) of an enum.

   [AttributeUsage(AttributeTargets.All)]
   class AllowedAttributeWithTypeArg : Attribute
   {
      public AllowedAttributeWithTypeArg(Type t) { }
   }

   class Foo1
   {
      // Direct reference to forbidden type in expression. Detected ok.
      public static Type TypeField = typeof(ForbiddenType);
   }

   [ForbiddenAttribute("Attributes defined in the foreign namespace detected ok")]
   class Foo2
   {   
   }

   // Reference to forbidden type in arg to attribute on class. Detected OK.
   [AllowedAttributeWithTypeArg(typeof(ForbiddenType))]
   class Foo3
   {
   }

   class Foo4
   {
      // Reference to forbidden type in arg to attribute on class field. Detected OK.
      [AllowedAttributeWithTypeArg(typeof(ForbiddenType))]
      public int x;
   }

   enum Foo5
   {
      Value1,
      // Reference to forbidden type in arg to attribute on enum value. Not Detected!
      [AllowedAttributeWithTypeArg(typeof(ForbiddenType))]
      Value2
   }

Graph/tree/list of existing dependencies

I'd like to be able to see some sort of analysis of existing dependencies between namespaces in my solution without having to set up rules in advance for what's allowed to access what.

System.ArgumentException: Should not be null or whitespace.

We're trying to use NsDepCop in a VS2017 solution inside a traditional-style csproj console app.

here's our config:

<?xml version="1.0" encoding="utf-8"?>
<NsDepCopConfig IsEnabled="true" CodeIssueKind="Warning" ChildCanDependOnParentImplicitly="true" InheritanceDepth="1">
    <Allowed From="*" To="*" />
    <Disallowed From="MyProgram.Runner.Domain" To="MyProgram.Runner.Adapters" />
</NsDepCopConfig>

Although NsDepCop appears to work correctly (i.e. warnings appear if we violate the rules), there is also an error, which causes the build to fail. Do you know what might be wrong? thanks

Exception during NsDepCopTask execution: System.ArgumentException: Should not be null or whitespace.
Parameter name: fromTypeName
   at Codartis.NsDepCop.Core.Interface.Analysis.TypeDependency..ctor(String fromNamespaceName, String fromTypeName, String toNamespaceName, String toTypeName, SourceSegment sourceSegment)
   at Codartis.NsDepCop.Core.Implementation.Analysis.Roslyn.SyntaxNodeTypeDependencyEnumerator.CreateTypeDependency(ITypeSymbol fromType, ITypeSymbol toType, SyntaxNode node)
   at Codartis.NsDepCop.Core.Implementation.Analysis.Roslyn.SyntaxNodeTypeDependencyEnumerator.<GetTypeDependencies>d__1.MoveNext()
   at System.Collections.Generic.List`1.InsertRange(Int32 index, IEnumerable`1 collection)
   at Codartis.NsDepCop.Core.Implementation.Analysis.Roslyn.TypeDependencyEnumeratorSyntaxVisitor.VisitGenericName(GenericNameSyntax node)
   at Microsoft.CodeAnalysis.CSharp.Syntax.GenericNameSyntax.Accept(CSharpSyntaxVisitor visitor)
   at Microsoft.CodeAnalysis.CSharp.CSharpSyntaxVisitor.Visit(SyntaxNode node)
   at Codartis.NsDepCop.Core.Implementation.Analysis.Roslyn.TypeDependencyEnumeratorSyntaxVisitor.DefaultVisit(SyntaxNode node)
   at Microsoft.CodeAnalysis.CSharp.CSharpSyntaxVisitor.VisitDelegateDeclaration(DelegateDeclarationSyntax node)
   at Microsoft.CodeAnalysis.CSharp.Syntax.DelegateDeclarationSyntax.Accept(CSharpSyntaxVisitor visitor)
   at Microsoft.CodeAnalysis.CSharp.CSharpSyntaxVisitor.Visit(SyntaxNode node)
   at Codartis.NsDepCop.Core.Implementation.Analysis.Roslyn.TypeDependencyEnumeratorSyntaxVisitor.DefaultVisit(SyntaxNode node)
   at Microsoft.CodeAnalysis.CSharp.CSharpSyntaxVisitor.VisitClassDeclaration(ClassDeclarationSyntax node)
   at Microsoft.CodeAnalysis.CSharp.Syntax.ClassDeclarationSyntax.Accept(CSharpSyntaxVisitor visitor)
   at Microsoft.CodeAnalysis.CSharp.CSharpSyntaxVisitor.Visit(SyntaxNode node)
   at Codartis.NsDepCop.Core.Implementation.Analysis.Roslyn.TypeDependencyEnumeratorSyntaxVisitor.DefaultVisit(SyntaxNode node)
   at Microsoft.CodeAnalysis.CSharp.CSharpSyntaxVisitor.VisitNamespaceDeclaration(NamespaceDeclarationSyntax node)
   at Microsoft.CodeAnalysis.CSharp.Syntax.NamespaceDeclarationSyntax.Accept(CSharpSyntaxVisitor visitor)
   at Microsoft.CodeAnalysis.CSharp.CSharpSyntaxVisitor.Visit(SyntaxNode node)
   at Codartis.NsDepCop.Core.Implementation.Analysis.Roslyn.TypeDependencyEnumeratorSyntaxVisitor.DefaultVisit(SyntaxNode node)
   at Microsoft.CodeAnalysis.CSharp.CSharpSyntaxVisitor.VisitCompilationUnit(CompilationUnitSyntax node)
   at Microsoft.CodeAnalysis.CSharp.Syntax.CompilationUnitSyntax.Accept(CSharpSyntaxVisitor visitor)
   at Microsoft.CodeAnalysis.CSharp.CSharpSyntaxVisitor.Visit(SyntaxNode node)
   at Codartis.NsDepCop.Core.Implementation.Analysis.Roslyn.RoslynTypeDependencyEnumerator.<GetTypeDependencies>d__3.MoveNext()
   at System.Linq.Enumerable.WhereEnumerableIterator`1.MoveNext()
   at System.Linq.Enumerable.<TakeIterator>d__24`1.MoveNext()
   at Codartis.NsDepCop.MsBuildTask.NsDepCopTask.ReportIllegalDependencies(IEnumerable`1 illegalDependencies, IssueKind issueKind, Int32 maxIssueCount)
   at Codartis.NsDepCop.MsBuildTask.NsDepCopTask.ExecuteAnalysis(IDependencyAnalyzer dependencyAnalyzer, String configFolderPath)
   at Codartis.NsDepCop.MsBuildTask.NsDepCopTask.Execute()	CrossBrandJobPoster.Runner			

Install config XML schema files with VSIX

The new VSIX v3 (coming with VS2017) allows installing artifacts to the Visual Studio Schema folder.

  • Q1: Shall I drop this feature in the MSI installer or provide it both in VSIX and MSI?
    • Providing two different ways to install a feature can confuse users. Also requires more testing.
  • Q2: Shall I drop MSI altogether?
    • Would save dev and test time to drop the WiX installer.
    • On the other hand it means dropping the machine-wide MSBuild integration feature too. Which is both good (pushes users to the recommended nuget way) and bad (there might be some scenarios where machine-wide MSBuild integration is better than per-project?).
  • Q3: Unfortunately adding the XML schema to the VSIX requires admin privilege for installing.
    • (A) No problem developers usually have this privilege.
    • (B) Provide two VSIX installers: one with the schemas (admin privilege required) and one without (no admin privilege required). Or one with only the analyzer and one with only the schema?

oh, so many questions...

Builds ocassionally hang

Occasionally, we see builds hang inside visual studio. No CPU or build progress. If I then kill the NsDepCop process, then it unblocks the build, leaving some projects as failed and others to complete.

I can't reproduce it, but could generate a process dump the next time it happens?

New feature - Type based dependency rules

I don't know if this is possible or not, but I would find it useful to be able to have rules associated with Types as well as namespaces. If you are trying to partition your code in "Vertical Slices"
(grouping by feature, rather than by layer) you often have several different infrastructure types in the same namespace, e.g. the FooController and FooRepository are in the same directory.

It would be cool to be able to prevent the FooRepository from referencing the FooController in this situation, maybe with <Disallowed From="*Respository" FromKind="Type" To="*Controller" ToKind="Type" />

NB this doesn't mean that namespace dependencies aren't being used, it's just that they are being used to keep features apart, e.g. preventing 'EmailTemplates' from talking to 'OrderProcessor;

I'm not sure if this would work best by identifying the Types using 1. name conventions, 2. base class conventions or 3. explicit marker attributes or 4. something else.

Warn when there is not used allowed rule

Given:
There is some rule in nsdepcop. Say <Allowed From="*" To="Foo"> and there is no references to Foo namespace in csproj

Actual result: no warning
Expected result: warning that rule is excess and could be removed.

Benefit: keeping your nsdepcop files nice and clean.

Disallow concrete type

Use case: For testability purposes accessing System.DateTime directly should be prohibited. All access should be via IEnvironmentInfo interface (eg. IEnvironmentInfo.GetDateTime).

Config should be enhanced to allow defining that a concrete type is accessible from a concrete namespace but inaccessible for all other namespaces.

Unable to communicate with NsDepCop service

I am installing NsDepCop for the first time. NuGet package v1.8.0 installed without issue and created config.nsdepcop. Also, the extensions NsDepCop VS2017 and NsDepCop Config XML Schema Support installed without issue. However, every time I build my project, I get the "Unable to communicate with NsDepCop service" exception. I have read the Troubleshooting page and #29, in which a similar issue was reported. I know that you've diagnosed the cause of this exception as a timing issue -- the client doesn't wait long enough for the server to spin up. However, I've increased the wait times drastically and continue to get the error every time.

AnalyzerServiceCallRetryTimeSpans="1000,10000,100000"

Do you have any suggestions about how I might further debug this issue?

-TC

Dependency config effectiveness metric

Calculate a metric that shows the effectiveness of the current dependency config.

DepConfigEffectiveness = (# of actual type-level dependencies in code) / (# of all allowed type-level dependencies)

The extreme cases would be:

  • 1 -> means the tightest dependency config that allows only the actually used dependencies.
  • Close to 0 -> means a very loose dependency config that allows everything so does not have much effect.

Performance concern: calculating the # of all allowed type-level dependencies would require counting all types in all namespaces in all referenced assemblies which sounds extreme.

Test analyzer with C# 7 features

See also #20 that was fixed without a repro.
Find out which C# feature caused the empty type name.
Do C# 7 features cause any other issues in the analyzer?

Dependency by inheritance is permitted

Let's say i want to separate data access logic from UI, and to enforce it i will create MyApp.UI and MyApp.Data namespaces with the following rules:

<Allowed From="MyApp.UI" To="MyApp.Data" />
<Allowed From="MyApp.Data" To="System.Data" />

What I want to enforce is that using System.Data from MyApp.UI is not permitted, and this seems to work properly. However if I create a class like this:

namespace MyApp.Data
{
    public class MyDataColumn : System.Data.DataColumn
    {
    }
}

I am able to use it in MyApp.UI, and this will generate a dependency on System.Data.

Is this intentional?

Support leading wildcard.

Hello, Thank you for this lib, it help us a lot.

I was wondering if it would be possible to support leading wildcard to achieve something like:
<Allowed From="*.UI" To="MyUiLib.*">

'Unable to communicate with NsDepCop service' when building 1 project. Works when building multiple projects.

Looking at the modules loaded by devenv.exe and msbuild.exe it seems that devenv.exe loaded NsDepCop.MsBuildTask.dll directly (instead of delegating this task to msbuild.exe). And because the NsDepCop VSIX is also loaded by devenv.exe, NsDepCop.MsBuildTask.dll finds a different instance (and version) of NsDepCop.Core.dll than expected. Instead of the one at the NuGet package folder (where NsDepCop.MsBuildTask.dll was loaded from) it finds the one at the VSIX folder where there's no NsDepCop.ServiceHost.exe so it can't activate it.

NsDepCop VSIX version: 1.10.0.240
NsDepCop NuGet package version: 1.9.0.234

Feature ideas - MaxWarnings and AutoLowerMaxWarnings

Hi, I have an idea for a couple of new settings which would be a big help when introducing NsDepCop into legacy projects.

Right now, if I were to add NsDepCop to a legacy project at work, there would be lots of violations as the layering isn't correct. This makes it hard to bring in as I can't set NsDepCop to raise errors (there are too many to fix) and if I set it to warning mode, then other developers will ignore the violations.

I was thinking that a new rule attribute MaxWarnings could be added that would throw an error if there are more than a certain number of warnings would be very useful. I could set it to the current number of violations and ensure that no new (or at least no more) violations are added, so the codebase wouldn't get any worse.

Another setting could then be AutoLowerMaxWarnings. This would change the MaxWarnings value in the config file to the current number of violations IF the current number is less than MaxWarnings. This would mean that developers could reduce the number of violations, but they couldn't increase them.

These settings could work both at an individual rule level, or for all rules.

What do you think? It would be great to have these features on the roadmap. If you like the sound of them, then I could maybe take a look when I get a chance*.

*I have a baby arriving in the next 3-4 weeks so it might be a while though!

Unable to communicate with NsDepCop service. All retries failed on CI Build

Hi,

First thanks for this tool, it's exactly what we needed to make sure our code is properly decoupled.

Next, unfortunately, I've never managed to make it run with our CI build. I'm using Azure Devops using my own build machine which a Win10 with latest VS2017 (same as my laptop). I always have this error message :

  Utilisation de la compilation partagée avec le compilateur du répertoire : C:\Program Files (x86)\Microsoft Visual Studio\2017\Community\MSBuild\15.0\Bin\Roslyn
NsDepCop_Analyze:
  [NsDepCop] Analysing project in folder: C:\agent\_work\10\s\src\Quadra.Affixe2.Application.Bodac.Private
##[error]Exception during NsDepCopTask execution: System.Exception: Unable to communicate with NsDepCop service. All retries failed. ---> System.Runtime.Remoting.RemotingException: Échec de la connexion à un port IPC : Le fichier spécifié est introuvable.
 

Server stack trace: 
   à System.Runtime.Remoting.Channels.Ipc.IpcPort.Connect(String portName, Boolean secure, TokenImpersonationLevel impersonationLevel, Int32 timeout)
   à System.Runtime.Remoting.Channels.Ipc.ConnectionCache.GetConnection(String portName, Boolean secure, TokenImpersonationLevel level, Int32 timeout)
   à System.Runtime.Remoting.Channels.Ipc.IpcClientTransportSink.ProcessMessage(IMessage msg, ITransportHeaders requestHeaders, Stream requestStream, ITransportHeaders& responseHeaders, Stream& responseStream)
   à System.Runtime.Remoting.Channels.BinaryClientFormatterSink.SyncProcessMessage(IMessage msg)

Exception rethrown at [0]: 
   à System.Runtime.Remoting.Proxies.RealProxy.HandleReturnMessage(IMessage reqMsg, IMessage retMsg)
   à System.Runtime.Remoting.Proxies.RealProxy.PrivateInvoke(MessageData& msgData, Int32 type)
   à Codartis.NsDepCop.Core.Interface.Analysis.Remote.IRemoteDependencyAnalyzer.AnalyzeProject(IAnalyzerConfig config, String[] sourcePaths, String[] referencedAssemblyPaths)
   à Codartis.NsDepCop.Core.Implementation.Analysis.Remote.RemoteDependencyAnalyzerClient.InvokeRemoteAnalyzer(IEnumerable`1 sourceFilePaths, IEnumerable`1 referencedAssemblyPaths)
   à Codartis.NsDepCop.Core.Util.RetryHelper.Retry[TResult](Func`1 func, Int32 maxRetryCount, BeforeRetryCallback beforeRetryAction)
   --- Fin de la trace de la pile d'exception interne ---
   à Codartis.NsDepCop.Core.Implementation.Analysis.Remote.RemoteDependencyAnalyzerClient.OnAllRetriesFailed(Exception exception)
   à Codartis.NsDepCop.Core.Implementation.Analysis.Remote.RemoteDependencyAnalyzerClient.GetIllegalTypeDependencies(IEnumerable`1 sourceFilePaths, IEnumerable`1 referencedAssemblyPaths)
   à Codartis.NsDepCop.Core.Implementation.Analysis.DependencyAnalyzerBase.<PerformAnalysis>d__9.MoveNext()
   à Codartis.NsDepCop.Core.Implementation.Analysis.DependencyAnalyzerBase.<AnalyzeCore>d__8.MoveNext()
   à Codartis.NsDepCop.MsBuildTask.NsDepCopTask.Execute()

I've read all other issues about this config (using 1.9.0), so it should have plenty of time to connect :

<NsDepCopConfig IsEnabled="true" CodeIssueKind="Error" ChildCanDependOnParentImplicitly="true" AnalyzerServiceCallRetryTimeSpans="100,1000,10000,30000">
    <Allowed From="*" To="*" />
    <Disallowed From="Quadra.Affixe2.Application.Bodac.*" To="Quadra.Affixe2.Core.Commun.*" />
    <Disallowed From="Quadra.Affixe2.Application.Bodac.*" To="Quadra.Affixe2.Application.Commun.Private.*" />
</NsDepCopConfig>

It's working perfectly on all developers laptops, the only problem is the CI builds.

Due to the way Azure devops is build, the MSBuild process should run as a system user (NETWORK_SERVICE IIRC), can it cause this problem ?

Thanks in advance.

Sébastien

Access denied exception when MsBuild.exe processes run under different user accounts

NsDepCop.ServiceHost.exe runs under the user account of the MsBuild.exe that first invoked it.
If there are other MsBuild.exe processes running under a different user account then those will receive Access denied exception when trying to communicate with NsDepCop.ServiceHost.

Either find out if the named pipe communication can be configured to accept connections from other user accounts or document it as a limitation.

Build integration: choose between global or per-project

At the moment the MSBuild integration is done globally (in the Custom.After.Microsoft.CSharp.targets file).

This should be decided by the user (at setup time or later) whether he wants this kind of build integration or he would prefer per-project integration (adding NsDepCop task to the concrete csproj files). This latter should be assisted with some VS integration feature and/or NuGet package.

Support .NET Core

Does NsDepCop work for .NET Core 2.0 projects? I was not able to find any specifics about supported .NET versions here on the GitHub pages.

Since I could not find it specified, I just went on and tried it. It seems to work OK from Visual Studio 2017, giving me the build errors I expected when I try to reference disallowed namespaces, etc. But when building from the command line by dotnet build, I get the following error:

<homedirpath>\.nuget\packages\nsdepcop\1.7.1\build\NsDepCop.targets(5,9): error MSB4062: The "Codartis.NsDepCop.MsBuildTask.NsDepCopTask" task could not be loaded from the assembly <homedirpath>\.nuget\packages\nsdepcop\1.7.1\build\..\tools\NsDepCop.MsBuildTask.dll. Could not load file or assembly 'Microsoft.Build.Utilities.v4.0, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a'. The system cannot find the file specified. Confirm that the <UsingTask> declaration is correct, that the assembly and all its dependencies are available, and that the task contains a public class that implements Microsoft.Build.Framework.ITask. [<full-project-file-path>.csproj]

I guess this issue might be relevant here.

Assembly and module attribute are not analyzed

E.g.:

[assembly: A.AllowedAttributeWithTypeArg(typeof(B.ForbiddenType))]
[module: A.AllowedAttributeWithTypeArg(typeof(B.ForbiddenType))]
[assembly: B.ForbiddenAttribute("foo")]
[module: B.Forbidden("foo")]

Wildcards don't work in front of namespace

I want to whitelist something like this:
<Allowed From="*" To="*.Contract" />
Which means that all namespaces should be allowed to reference namespaces ending on .Contract.

But this doesn't seem to work.

"Master" config file for default rules

Besides the project level config files there should be a global and/or solution level "master" config file that contains config info that you don't want to specify in each project-level config file.
(eg. the *->System rule)

Location for a "global" config file: next to the MsBuild task dll. (?)
Location for a solution level config file: next to the sln file.

Convert csprojs to new format

Convert all projects to <Project Sdk="Microsoft.NET.Sdk"> format.
Change from packages.config to PackageReference entries.

NuGet install

NsDepCop install as NuGet package. (Similar to StlyeCop.)

  • Is it possible to add a custom build step with NuGet?
  • Can it replace the current MSBuild integration?

Fix branch names

  • rename master to VS2012
  • branch nem master from VS2015
  • make master the default branch

VisibleMembers should allow defining the surface of a subtree

At the moment, with Allowed/VisibleMembers you can define the surface of only a single namespace. (The To namespace can not be a subtree.)
Eg.

    <Allowed From="Codartis.NsDepCop.Core.Factory" To="Codartis.NsDepCop.Core.Implementation.Analysis.NRefactory">
        <VisibleMembers>
            <Type Name="NRefactoryDependencyAnalyzer" />
        </VisibleMembers>
    </Allowed>

It should be allowed to define the surface of a subtree as well.
Eg.

    <Allowed From="Codartis.NsDepCop.Core.Factory" To="Codartis.NsDepCop.Core.Implementation.*">
        <VisibleMembers>
            <Type RelativeName="Analysis.ConfiguredAnalyzer" />
            <Type RelativeName="Analysis.IAnalyzerFactory" />
            <Type RelativeName="Analysis.NRefactory.NRefactoryDependencyAnalyzer" />
            <Type RelativeName="Analysis.Roslyn.RoslynDependencyAnalyzer" />
            <Type RelativeName="Config.XmlFileConfigProvider" />
        </VisibleMembers>
    </Allowed>

In this case the Type elements must describe not only the type name but also its relative namespace path.

The same should apply to VisibleMembers elements with the OfNamespace attribute.

Frequent failures on CI builds (error NSDEPCOPEX)

We frequently get build failures on our CI build agents:

error NSDEPCOPEX: Exception during NsDepCopTask execution: System.Exception: Unable to communicate with NsDepCop service. Exception: System.Runtime.Remoting.RemotingException: Failed to connect to an IPC Port: The system cannot find the file specified.

Running the build again usually succeeds.

Turn off analysis with some global switch

Analysis can take a significant time. When there's a need for a quicker build (without analysis) there should be some global switch to achieve it. Eg. an environment variable?

VS2017 Support

Hi, is VS2017 support planned? Thanks for the awesome tool.

If no source file have changed then do not execute the analysis.

Similarly to incremental compilation NsDepCop should not run when no source file have changed.

Currently analysis is run after the build target.
<Target Name="NsDepCop" AfterTargets="AfterBuild">

Maybe it would be better to make it part of the compilation?

<PropertyGroup>
  <TargetsTriggeredByCompilation>
    $(TargetsTriggeredByCompilation);
    NsDepCop
  </TargetsTriggeredByCompilation>
</PropertyGroup>

Still it does not take into account whether config.nsdecop was changed or not.

[Q] Are transient dependencies supported?

Hello,

Is it possible to capture transient dependencies on type level?
Let's say we have a dependency chain A->B->C:

namespace A {
 class ClassA {
    public B.ClassB B = new B.ClassB();
 }
}

namespace B {
 class ClassB {
    public C.ClassC C = new C.ClassC();
 }
}

namespace C {
 class ClassC {
    public int i = 0;
 }
}

I would like to implement a rule disallowing A->..->C.
I couldn't make it work with current NsDepCop.
Is it possible?

I need to convert big code base to .NET Standard and some of lower layers of the code-base have .NET Standard-incompatible references: to System.Forms, etc. I need to know which upper level code transitively depends on the incompatible stuff (and which doesn't). Is it possible to find out with the help of NsDepCop?

I see my question is related to #35

Exclude generated files from analysis

Huge generated files can take a long time to analyze while providing little value. There should be a way to exclude files from the analysis. Either by path and/or by filename pattern (eg. *.g.cs).
(Of course it could be used to exclude any files, not just generated ones.)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.