NDepend – “SQL” for your code

Some time ago I received an offer for a NDepend Professional license. I was vary at first since Credibility and Free Stuff is hard to mix together, but I accepted it because it was on my list of tools to play around with anyway. It took me several months to actually use it in a real application, but here are some thoughts about it. Again, I received the license for free but the posting here is unbiased.

I guess unbiased reviews need to start with something negative to support the claim that the review is truly unbiased Smile So to roll with it, let me say that you shouldn’t judge the product by it’s homepage which sadly looks like a 2003-ish WebForms site. The application itself isn’t the best looking one either, but it has fancy colors and stuff. It also looks like 2003-Windows XP Luna when in 2011 we’ve moved back a bit to clean, serious, calm colors. But well, again, this is about the product.

My first question when looking at commercial software is of course: What problem does it try to solve, and is that problem really a problem?

NDepend is an analyzer to find some flaws that easily fall through the cracks: High Cyclomatic Complexity (which is not a problem when the code is still fresh in your head, but causes nightmares 6 months down the road when you need to find a bug in it). Dependencies with more dependencies with more dependencies with more… Comparing two code bases for a list of all changed methods.

It does a lot more, but what I was interested right now was their Code Query language, CQL. It’s like SQL, but for code.

For example, I’ve analyzed the Code, added a public method, analyzed again and the performed a “SELECT METHODS WHERE WasAdded AND IsPublic”. As a result, I get a list of all newly added Public methods:

image

What problem does this solve? It solved the problem of Diff Tools being unaware what they are diffing. Let’s say you merge a large commit that has 200 changed files. You glance at them and see that there’s tons and tons of tab vs. spaces changes, many added code comments, some refactoring. It’s a very bad signal to noise ratio when in reality you are mainly concerned with “How did functionality change?”. Of course, you can now easily say “One change per commit. Commit Messages are enough documentation. Do not commit both functional and semantic changes” and you are right – but this is not how the real world works.

Maybe you don’t even know the code base because your predecessor didn’t do a good job documenting stuff or even checking stuff into source control and now you have two codebases (one possibly a result of decompiling the assembly) and need to get an overview.

The CQL Query edit window has IntelliSense which is really helpful, but not without it’s flaws: “SELECT methods  WHERE  WasAdded” does not work, it needs METHODS to be uppercase. Also there seems to be no "SELECT * WHERE WasAdded”

The one thing I really dislike about this feature though is that it’s relatively complex to setup: Ideally I’d just love to tell NDepend “Here’s two Visual Studio solutions and/or assemblies, please analyze them and show me a list of functional differences”. Specialized tools like Inca are available to make that easier of course.

Methods with a lot of instructions

You can query for a lot of really neat stuff, like the number of IL Instructions:

SELECT TYPES FROM ASSEMBLIES "SWiki" WHERE NbILInstructions > 300 ORDER BY NbILInstructions DESC

image

This is a LOT more useful than lines of code (which is also possible) because I can easily write very terse but unneccessarily complex code among the line of this:

for (int i = 0, y = 1, z = 13; i++ < 10 && ++y < 8; CallSomeMethod(i, y, z)) ;

Only to save a few lines while still writing insanely crappy code that would make a C++ developer proud.

Methods called by many other methods

What else can we query by? Most Used Methods is nice, ignoring .net Framework assemblies and Properties:

SELECT TOP 50 METHODS WHERE !IsInFrameworkAssembly AND !IsPropertyGetter AND !IsPropertySetter  ORDER BY MethodCa DESC

image

This is different from running a profiler, because this analyzes all the theoretical calls: There’s 23 places in my source where a certain constructor is called. Sadly there seems to way to get the Method Name as well as the Signature… Note that this is NOT a profiler thing: Just because the ctor is called in 23 different places does not mean that it needs to be performance critical because no statement how often it is called is made. This list is not a “Where to optimize speed next”, it’s a “Do we have any methods that should be abstracted away a bit more?” thing.

Classes implementing an Interface

MSDN has a list of derived classes on certain base classes, but it lacks this for Interfaces. Quick, tell me which classes implement IPrincipal? The MSDN Page does not show, but NDepend does:

image

I was looking for ages for a way to “Query” MSDN like that, and NDepend does it once you created a project to analyze all the .net Framework assemblies (and any additional ones of course).

Comparing SharePoint 2007 to 2010

As NDepend works against assemblies rather than source code, you can run analysis of SharePoint 2007 DLLs, then the SharePoint 2010 ones. The result is a full report about public API changes.

Even better: Run analysis before and after installing a Hotfix and see what actually changed and analyze your custom code precisely for these changes.

What about existing Code Analysis and Resharper users?

Now, I’m using Visual Studio 2010 Premium with Code Analysis and ReSharper which means that a lot of the simple mistakes are already caught without NDepend: Making Fields readonly, marking assemblies CLSCompliant, methods that don’t use “this” could be static, methods with way too many dependencies etc. pp.

For some of the more common problems, users of Code Analysis should better write their own rules so that they run on every build. But when it comes for just quickly querying the code prior to a refactor (How much stuff is affected?) or just for finding stuff (I wonder what ActionResults ASP.net MVC has, and which ones we’ve added?) NDepend is a great resource.

Finding duplicate File names in a directory tree

Just a little one liner. Essentially I have a nested file system structure with a lot of subfolders and I wanted to know if there are duplicate file names.

This does the trick for me:

find . -iname "*.txt" | xargs -I {} basename {} | uniq -d -i

So what this does:

  1. Call find to find all files that match *.txt (case insensitive) in the current folder and all subfolders
  2. Call basename to turn /path/to/file.txt into file.txt. We have to use xargs since basename does not seem to be able to read from stdin
  3. Call uniq to check the list for duplicates. -d means that we only show duplicates (default is to show unique values) and -i performs a case insensitive comparison

Sidenote: As much as I love working with Windows, it just does not stand a chance against a long chain of simple, small, well-defined UNIX tools that are piped together. As much as PowerShell is a step in the right direction, it's not the same because the philosophy of having tons of very limited and specialized tools doesn't seem to exist in the Windows universe - most command line tools do too much. Also, UNIX has a 30 year head start against PowerShell.

Connected Web Parts are bugged in SharePoint 2010

Update: This is an intentional design change, see the Microsoft answer in this thread.

Just stumbled upon a bug in SharePoint 2010. Imagine this scenario: You have two lists and add them to a Site as DataForm WebParts. You then configure the Web Parts so that one of them sends Filter values to the other one and uncheck the option for "Send first row to connected Web Parts when page loads". You refresh the Page and notice that the list that receives the Filter (the Consumer) does not show any items because the list that provides the Filter (the Provider) does not have any items selected.

In SharePoint 2007, not selecting an item in the Provider List would cause the consumer List to display all items instead, which was (at least for us) highly desirable. In SharePoint 2010, you have to select an Item in the Provider to provide a filter and there is no way to have the Consumer List display all items anymore.

The reason why I think this is a bug is the result of an extended Debugging session that eventually led me to the class Microsoft.SharePoint.WebPartPages.DataFormWebPart and specifically it's method ApplyReceivedFilterData. I'm not going to paste the source of this class, but the culprit is this line: if (dictionary2[str] != null)

This is supposed to only add Filters that have a value and skip the ones that are null. The problem is that dictionary2[str] is not null but DBNull, which then causes SharePoint 2010 to process the value anyway and generate a nasty <Query><Where><IsNull><FieldRef Name="FieldToReceiveFilter" /></IsNull></Where></Query> in the SelectCommand of the underlying DataSource

Unfortunately, DataFormWebPart.ApplyReceivedFilterData is not virtual, so sub-classing it does not seem to be an option. Not sure if there is a good workaround for this. I verified this behavior in both RTM and December 2010 Hotfixed versions of SharePoint 2010.

Edit: Just checked the SharePoint 2007 DataFormWebPart.ApplyReceivedFilterData() in Reflector and lo and behold, they did check for DBNull in 2007:

        Label_0046:
            if (current[str] is DBNull)
            {
                goto Label_006D;
                // Note by myself: Label_006D is the call to MoveNext, aka. continue
            }

A little Eggtimer script using Growl

The quasi-standard notification system for Mac OS X is Growl, and one of the extras included in the download is the growlnotify app that lets you push notifications from shell scripts. Then, there is the at command which allows to execute a job at a given time. It's essentially another way to modify the crontab, that doesn't use the crontab directly.

So with a notification system and a scheduler at our disposal, I thought it would be good to write a little eggtimer script so that I can specify "Remove Pizza from oven in 10 minutes". I'm sure there are tons of graphical tools available, but I prefer a simple shell script.

The growl side is easy, this command needs to be executed:

growlnotify -t "Reminder at 03:54" -m "Remove Pizza from oven" -s -a iCal

The -t parameter specifies the title (even though the manpage incorrectly states "this does nothing"), -m is the message, -s means it's sticky (so it doesn't disappear unless explicitly closed) and -a specifies the icon to use, in this case the iCal icon.

The at command is used to create jobs that run at a specified time. However, it requires another "service" to run, called atrun. By default, this is disabled. Check the atrun manpage for the command to enable it, on my OS X 10.6.6 it's

sudo launchctl load -w /System/Library/LaunchDaemons/com.apple.atrun.plist

I found the syntax of at a bit weird as it kept complaining about garbled or incomplete time. It actually needs to read a whole input from stdin rather than just accepting a single command. So the invocation looks like this:

at now + 10 minutes << eol
growlnotify -t "Reminder at 03:54" -m "Remove Pizza from oven" -s -a iCal
eol

That works, but of course it's WAY too much to type for us lazy people :) So let's wrap this in another shellscript that accepts two parameters: A number for "Remind in X minutes" and a message:

#! /bin/zsh
function verifyminutes () {
  echo -n $1 | grep -Eq "^[0-9]+$"
  echo $?
}
function gettargettime() {
  date -v +$1M "+%H:%M"
}
function getmessage() {
  # function to collapse arguments $2..$n together (skipping $1)
  # I'm pretty sure there is a better way of doing this
  local FIRST_PARAMETER=0
  for i;
  do {
    if [ "$FIRST_PARAMETER" -eq 0 ]; then
      FIRST_PARAMETER=1
      continue
    fi
    echo -n $i" ";
  }
  done
  echo "\b"
}

local ISNUMBER=`verifyminutes $1`
[[ -z $1 || -z $2 || "$ISNUMBER" -gt 0 ]] && {
  echo "usage: $0 minutes message"
  exit 1
}

local TARGET_TIME=`gettargettime $1`
MESSAGE=`getmessage $@`
echo "Reminder set at $TARGET_TIME: $MESSAGE"

at now + $1 minutes >/dev/null 2>&1 << eol
growlnotify -t "Reminder at $TARGET_TIME" -m "$MESSAGE" -s -a iCal
eol

exit 0

Usage of this script is simple, just call eggtimer 10 Remove Pizza from oven and 10 minutes later you will get a Growl notification.

PS: If you are wondering about the getmessage function: Normally if you have spaces in an argument, you need to enclose the entire message in quotes. I wanted to get rid of the quotes, hence I'm collapsing all parameters after the first one together.

Eye-Fi Pro X2

A few weeks ago I decided that it was time to retire my trusty old Canon Powershot A410 Camera. It's still a good camera (although low-light sucks), but I wanted something with a bit more zoom and resolution, and preferably RAW and manual Shutter/Aperture Settings. I ended up buying a Panasonic Lumix DMC-FZ35.

Now, the camera is nice, but has one major drawback: A non-standard USB Port which requires the special Panasonic USB Cable - this sucks. Also, I got a 16 GB SDHC Card but my existing USB SD Card Reader is an old one that does not support SDHC. Also, removing the card from the camera for syncing every time isn't that great either as the camera does a complete reboot every time I open the battery cover to remove the card.

Scott Hanselman had a posting about his digital camera history and mentioned a special SD Card with Wi-Fi connectivity, made by Eye-Fi. Looking at their website, they have four different cards, but only one that supports RAW. I bought the Pro X2 on Amazon for about $99.

The card comes with a USB SDHC Card Reader, and the card conveniently contains the installation software for Windows and Mac OS X. You need to configure it on a Mac/PC first so that it connects to your Wi-Fi. Registration requires internet access, as you need to create an account with Eye-Fi and register your card with it - I'm not too impressed with that, as I think it's unnecessary. I understand that certain premium features like automatic Geotagging should be restricted to an account, but I feel that the card should 'just work' without any account. I just hope Eye-Fi never goes out of business.

This account allows for some nice features though, if you choose to do so: You can automatically upload pictures to your account, even through hotspots. So if you are on the road and the card connects to a hotspot, it can automatically upload your pictures to Eye-Fi and you can then download it to your PC when you are at home again. Also, it can automatically upload photos to popular photo sharing sites like Picara, Flickr or Facebook.

On my Mac I use Picasa as my photo application, because iPhoto does not support the RAW format of my camera (neither does Preview). One of the nice things is that Eye-Fi Center allows me to configure separate directories for JPG and RAW photos (my Camera is set to save pictures as both RAW and JPEG), so I can put RAW into my Picasa watch folder. Unfortunately, automatic Geotagging does not work for RAW files, only for JPG so I might need to write a script that copies that info from the JPG to the RAW at some point.

The other great feature is Endless Memory. Basically if the card is filled to a certain percentage, it will automatically delete older photos, but only ones that were transferred to the PC before.

Overall, the card works just as I expect it to be: magically. The little Eye-Fi Helper app that runs in the background of my Mac automatically picks up pictures if the card is in my network, puts the JPG in one and the RAW files in another folder where Picasa picks it up. No more proprietary cable or removing the card all the time, it just works.

The only downside I can see is that 8 GB isn't exactly a lot nowadays, but I can use my old 16 GB card as an emergency spare in situations where space really becomes a problem.

Misc Utilities Library

I have various code snippets here and there in my blog and various tools, so I thought I'll just bundle them all together. I have created a project on GitHub for this, licensed under WTFPL as usual. There are no binary downloads because you're supposed to just cherry pick the stuff you want into your own project, but if you want to compile an assembly and use that, feel free to do so.

References for this on my blog:

Tron Legacy

I saw Tron Legacy on Friday and thought I'd write down a few thoughts. First, I only saw the first Tron in full length last year, but ever since I saw some bits of it in my childhood (and played the many light cycle games) it impacted me. It came out in 1982, at a time where Arcades were still popular but home computers were still mainly something for geeks. It was extremely visionary and revolutionary at the time, and it still holds up very well. Yes, the hand colored black and white scenes show their age, but the movie just has so much spirit to still be fantastic.

Of course, the late 70's/early 80's were a great time to be visionary. William Gibsons Neuromancer came out in 1984 and had this very vivid description of cyberspace, years before Hackers gave us another iconic vision. Hajime Sorayama had his Sexy Robots artbook published in 1983 - I'm absolutely sure that you saw some of his pictures, as they were in all the computer magazines for more than a decade. WarGames taught us that the only winning move is not to play, and Synthesizer Music was still en vogue, especially in TV and Movies. I was born in the early 80's, so these things shaped my childhood and therefore who I am now. I belong to the generation that loaded it's (mostly pirated) games with LOAD "*",8,1 and I remember when the Internet first came up and I could waste hundreds of dollars (actually Deutsche Mark) of my parents hard-earned money browsing the web on my 14.4k modem after installing a TCP/IP stack on my Amiga.

So yeah, Tron. It polarized: People either hated it or had it fundamentally impact their future life. It wasn't a commercial success, but it had a cult following. It's one of those movies that should really have a sequel, but which at the same time can't really have a working sequel. What would a second movie improve? The story wasn't that great and the visual effects were now done. A mere 10 years later - in 1992 - Terminator 2 would destroy all limitations of special effects, and three years later, Toy Story would break down the last remains of CGI limitations. So a sequel that has no place in our time, to a movie that was a commercial failure? That has to be a disaster, right? Wrong. Tron Legacy isn't as Visionary as the first one and won't make the same impact, that's for sure. It may not even have any impact on the current generation of kids and adolescents (It's hard to believe, but the youth of today doesn't necessarily know what a floppy disk is, they never spent hours setting up a BNC network to play Doom with friends and never had a chance to listen to the glorious music generated by the SID chip). It's Fan Service, it's a movie for the people who attend ComicCon since 30+ years. It's a movie for the people who saw Chris Metzen talk about Geeks and kept nodding in agreement all the time.

Okay, 500 words in and no word about the actual movie yet, so enough of that nostalgia. I don't want to spoil the story too much here, although the trailers already did that pretty well (Trailers 2 and 3 are awful. Why do movie trailers these days have to spoil all the major plot twists? I noticed that on other movies as well. What's the point of watching a Movie if you already seen all important scenes during the trailers?). So you got Kevin Flynn disappearing and his Son going into the Grid. The story isn't award-worthy, but it keeps the movie going along nicely. As said above, the movie is fan service, so it was quite a few references and one-liners that cater us old people - although at times it can be a bit cheesy, for example when a certain WarGames quote is said almost word for word. There is also a scene that seems to be heavily inspired by the newer Star Wars movies - but it works. Bruce Boxleitner returns (although his role is very small), and so does Jeff Bridges as Kevin Flynn. He nails the role perfectly. It's a pleasure to watch him, he is so relaxed yet serious. The rest of the cast is equally great - I never heard of Garrett Hedlund before, but he plays a great Sam Flynn and really passes as the son of Kevin Flynn in his looks, behavior and dialogue without being a verbatim copy. The female lead - Olivia Wilde - is an equal as well, not just the pretty girl that's just there for the looks.

With the technology of this generation, they made the movie look spectacular, but not sterile. Sure, it's a very polished world, but one that still has character and spirit. And it's a stylish world, a high gloss world, a world where Beau Garrett is wonderful eye-candy without feeling out of place and not just (completely) thrown in for the looks. The Light Cycle sequences look spectacular, and so does the Disc Wars game, and so do the costumes.

Tron Legacy is a highly refined, polished and evolved sequel to Tron that manages to introduce strong new elements and characters while staying true to the original. Does it bring anything really new to the table though, something that the original didn't have? Does it have one really memorable, stand out element? In my opinion yes: The Music. Of course, the original Tron had a great score by Wendy Carlos that is playing throughout most of the movie and nicely adds atmosphere. But the Tron Legacy score is lightyears ahead. It's made by Daft Punk (who have a great cameo in the movie), which is reason enough already to like it. It seems that parts of the movie were actually but to fit the score, rather than the other way round. I can't praise the score enough, I really can't. It's perfect from the first moment to the end. Especially the end. The Tron Legacy End Titles song is finally a reason to stay during the credit roll and not just get up and leave. The only caveat I might have is that sometimes the music is too loud compared to the voices.

I did watch the movie in IMAX 3D, and if I could give one advice to maximize your viewing experience, then it would be this: Do not waste money watching it in 3D, the experience is utter crap. It even says at the beginning that some scenes are 2D (all the scenes in the real world are), but even the ones that are 3D don't work. So far every movie I've seen in 3D - both IMAX 3D and real 3D - was a huge disappointment, so Tron Legacy is the last 3D movie I've seen until someone invents proper 3D without the glasses or I get invited for free. The IMAX experience itself is great though, with the usual caveat that there are only about 20 good seats in an IMAX theater.

Does Tron Legacy have its cheesy moments, non-working gags and a Michael Sheen that is slightly overacting? Oh Yes. Is it going to be as visionary as the first one? Nah. Should you watch it if you didn't like the first one? Possibly not. Will the story win an award? Neither the Academy award nor the golden raspberry. Does it do a great job introducing the universe to people who haven't seen Tron? I don't think so, you should definitely watch Tron first.

But would I recommend it? Absolutely. Whether it will have a lasting impact or not, it is a great experience. Can't wait for the BluRay to come out.

NuGet: Description is Required

Just got a new error message after updating to ASP.net MVC 3 RC2 which seems to contain a new NuGet version (displays as 1.0.10128.89 in Visual Studio Extension Manager).

Any attempt to install a package - be it through 'Add Library Reference' or through PowerShell Install-Package - displays an error message: Description is required.

Turns out that one of the nuspec files has indeed an empty <description /> tag. Sadly, that breaks the entire repository.

The solution is to put in a description and rebuild the nupkg. In parallel, I have filed a bug on CodePlex in the hope that a single broken package does not break the entire Repository anymore.

SPWebApplication.BlockedFileExtensions does not contain dots

Just a reminder post for me: SPWebApplication.BlockedFileExtensions outputs a Collection<string> that does not contain the leading dot.

However, Path.GetExtension does return the extension with a dot (or string.Empty in case the file does not have an extension).

Additionally, there may be upper/lowercase conflicts.

Writing a BF Compiler for .net (Part 7: The ret instruction)

Yesterday I have concluded the .net BF series with the explanation and code of the .net BF Compiler. But there was one thing that is important and that was unclear in the post: The ret instruction.

Remember how the compiler emits a ret instruction at the end of the constructor and Execute method? I said it's optional and only required for verifiable code. Well, I've asked on StackOverflow in the meantime and got the answer I was looking for:

Control is not permitted to simply “fall through” the end of a method. All paths shall terminate with one of these instructions: ret, throw, jmp, or (tail. followed by call, calli, or callvirt).

(ECMA-335; 12.4, 6)

So, there you have it: Make sure each method ends with one of the above instructions.