Are SCM check-out’s contemporary?

My VCS story began with Microsoft Visual Source Safe. I was happy... I had my files versioned. I could view differences in file versions. I could restore previous versions. I could view the history of a file. ... until the IDE started to crash, I had corrupted files and so on. http://www.flickr.com/photos/nesster/5823554695/ So I gave CVS and then SVN and TFS a try. I was happy... I could work with branches I could version source code “over HTTPS”. I could view file versions over HTTPS. ... until I saw a GIT introduction on the .NET Open Space presented by Alexander Groß. I was shocked about how I had worked before! He showed that it is not necessary to explicitly check-out and check-in files. I almost all areas of software development we try to align with business and to focus on the features that help or supports users or customers at their processes (E.g.: OOD, DDD, etc...). So why should I commit a change set just because I want to rename a file a second time? That is not a feature. It’s not even the result of a refactoring. Its just to satisfy the tool. Here are a few reasons why: Refactoring is an important part of the process to maintain a healthy and high quality code base. It means changing the structure... Naming I one of the hardest disciplines in software development. I don’t thing it helps anybody when there is an additional burden called the check-in. From my experience It holds people back from improving the code. 2010 I moved into the DVCS world. I started with HG and later moved on to GIT. I am happy... I can focus on the features. The SCM understands branching The SCM understands refactoring The SCM understands merging Last year on the NRW Conf my friend Ilker Cetinkaya held a lecture about commit messages. In his opinion the commit message should tell a story and answer the questions: What, why & how. He sowed really nice examples of commit messages almost equal to a blog post or a developer diary. Focusing on the Feature (LOB) and providing details about the technical realization. Markdown is an ideal format here. I cannot agree more. After the conference we discussed non-feature-commit-messages and agreed there should just be one: “Rechnerwechsel” the German term for “Switching the Machine”. When I join a project of a customer I sometimes still see SCM systems that still require explicit check-ins. My pleading Let developers focus on the features to deliver better results. Everybody has just 100% to give. Don’t take even a few percent of the developer productivity to hassle with a SCM just for the SCM. Version control exists to support people. Not to change the way people work: The motivation and empowerment of programmers has a direct and strong relationship to the quality of  the software.

NDepend customizing rule: Declare types in namespaces

NDepend is a tool that offers a wide range of features to let developers analyze a .NET code base. It comes with about 200 built in rules. But there are a few default rules that do not fit “my rules”. This blog post shows how to customize one and even more important why. Avoid namespaces with few types In general types should be placed in namespaces. But compiler generated types (caused by linq queries) are sometimes not. Here is my fixed rule to skip the compiler generated types: warnif count > 0 from t in Application.Namespaces.Where(n=>n.Name == ""). SelectMany(n=>n.ChildTypes) where !t.IsGeneratedByCompiler select new { t, }

NDepend customizing rule: Avoid namespaces with few types

NDepend is a tool that offers a wide range of features to let developers analyze a .NET code base. It comes with about 200 built in rules. But there are a few default rules that do not fit “my rules”. This blog post shows how to customize one and even more important why. Avoid namespaces with few types I observed that the original rule outputs an unnecessary line for namespace {} because of the compiler generated classes (caused by linq queries). Here is my *fixed* rule to skip “0 types“ in the result: warnif count > 0 from n in JustMyCode.Namespaces let types = n.ChildTypes.Where(t => !t.IsGeneratedByCompiler) where types.Count() < 5 && types.Count() > 0 orderby types.Count() ascending select new { n, types }

NDepend customize rule: Avoid defining multiple types in a source file

NDepend is a tool that offers a wide range of features to let developers analyze a .NET code base. It comes with about 200 built in rules. But there are a few default rules that do not fit “my rules”. This blog post shows how to customize one and even more important why. Avoid defining multiple types in a source file I completely agree, with one exception: When having a generic and a non-generic type e.g. MyClass and MyClass<T> warnif count > 0 let lookup = Application.Types.Where( t => t.SourceFileDeclAvailable && !t.IsGeneratedByCompiler && !t.IsNested ).ToMultiKeyLookup( t => t.SourceDecls.Select(d => d.SourceFile) ) from @group in lookup.Where( g => g.Select( x => x.Name.IndexOf("<") > -1 ? x.Name.Substring(0, x.Name.IndexOf("<")) : x.Name ).Distinct().Count() > 1 ) let sourceFile = @group.Key let typeWithSourceFileName = @group.FirstOrDefault( t => t.SimpleName == sourceFile.FileNameWithoutExtension ) let typeIndex = typeWithSourceFileName ?? @group.First() select new { typeIndex, types = @group as IEnumerable<IType>, typeNames = String.Join( ", ", ((IEnumerable<IType>)@group). Select(t1=>t1.Name). ToArray() ), sourceFile.FilePathString }

NDepend customize rule: Types too big

NDepend is a tool that offers a wide range of features to let developers analyze a .NET code base. It comes with about 200 built in rules. But there are a few default rules that do not fit “my rules”. This blog post shows how to customize one and even more important why. Types too big I use extension methods to collect several functionality for e.g. framework types as string. Each Extension-Class is typically  spread across several files and partial to keep overview and maintainability. NDepend analyses on assembly basis and therefor cannot know about my tricks. But I can put some knowledge into the query: warnif count > 0 from t in JustMyCode.Types where t.NbLinesOfCode > 500 && !t.Name.EndsWith("Extensions") orderby t.NbLinesOfCode descending select new { t, t.NbLinesOfCode, t.NbILInstructions, t.Methods, t.Fields }

NDepend customize rule: Quick summary of methods to refactor

NDepend is a tool that offers a wide range of features to let developers analyze a .NET code base. It comes with about 200 built in rules. But there are a few default rules that do not fit “my rules”. This blog post shows how to customize one and even more important why. Quick summary of methods to refactor This rule gives you a quick overview of what needs to be refactored. I adjusted the rule so that compiler generated delegates that have a high “IL Nesting Depth” do not appear.Sample code for this case: var tablesNames = from tableRow in conn.GetSchema("Tables").Rows.Cast<DataRow>() let tableName = tableRow["TABLE_NAME"].ToString() where !tableName.Contains("$") ... select tableName; warnif count > 0 from m in JustMyCode.Methods where m.NbLinesOfCode > 50 || (m.NbILInstructions > 200 && m.ILCyclomaticComplexity > 50 ) || m.CyclomaticComplexity > 20 || m.ILCyclomaticComplexity > 50 || (m.ILNestingDepth > 5 && m.ILCyclomaticComplexity > 10) || m.NbParameters > 5 || m.NbVariables > 20 || m.NbOverloads > 25 select new { m, m.NbLinesOfCode, m.NbILInstructions, m.CyclomaticComplexity, m.ILCyclomaticComplexity, m.ILNestingDepth, m.NbParameters, m.NbVariables, m.NbOverloads }

NDepend customizing rule: Static fields should be prefixed with a 's_'

NDepend is a tool that offers a wide range of features to let developers analyze a .NET code base. It comes with about 200 built in rules. But there are a few default rules that do not fit “my rules”. This blog post shows how to customize one and even more important why. Static fields should be prefixed with a 's_' I use underdashes for instance fields and therefor I have a custom rule for static fields. They tend to look even more scary (and that’s what they should) if prefixed with ‘_s_’. So here is my rule: warnif count > 0 from f in Application.Fields where !f.NameLike (@"^_") && f.IsStatic && !f.IsLiteral && !f.IsGeneratedByCompiler && !f.IsSpecialName && !f.IsEventDelegateObject select new { f, f.SizeOfInst }

NDepend customize rule: Instance fields should be prefixed with a 'm_'

NDepend is a tool that offers a wide range of features to let developers analyze a .NET code base. It comes with about 200 built in rules. But there are a few default rules that do not fit “my rules”. This blog post shows how to customize one and even more important why. Instance fields should be prefixed with a 'm_' I prefix instance fields with a ‘_’ not with ‘m_’ so I need to customize the default rule: warnif count > 0 from f in Application.Fields where !f.NameLike (@"^_") && !f.IsStatic && !f.IsLiteral && !f.IsGeneratedByCompiler && !f.IsSpecialName && !f.IsEventDelegateObject select new { f, f.SizeOfInst }

Validating Code Quality with NDepend

Patrick Smacchia’s NDepend is a great tool to improve code quality and should be run quite regularly. It can be run as a strand alone GUI tool, from inside Visual Studio and as part of your build process. I’ll use the tool over the next few weeks to analyze and improve the quality of one of my personal code bases. I’ll try to share my experiences beside tips and tricks as well as giving feedback to Patrick. Code Rules an Queries At first I’d like to highlight one of the most powerful features: Code Rules an Queries. This lets query your code base over LINQ queries thanks to CQLinq. There are about 200 default rules. The power really evolves as you start customizing these and further on start writing your own rules. Here is an example: from m in Application.Methods where m.NbLinesOfCode > 30 && m.IsPublic select m And a screenshot of the Editor: Wishlist As X-Mas is soon I’ll write down a few things I would have expected or that would improve the tooling experience. Tab a selection in “Query and Rules Edit” Currently a tab on a selected range removes the range. Tabbing helps me to keep code readable.