Steve Lange @ Work

Steve Lange's thoughts on application lifecycle management, Visual Studio, and Team Foundation Server

April, 2011

  • Steve Lange @ Work

    Running Code Metrics as Part of a TFS 2010 Build – The Poor Man’s Way

    • 8 Comments

    Code Metrics, not to be confused with code analysis, has always been tough impossible to run as part of a build in Team Foundation Server.  Previously, the only way to run code metrics was to do so inside Visual Studio itself.

    In January, Microsoft released the Visual Studio Code Metrics PowerTool, a command line utility that calculates code metrics for your managed code and saves the results to an XML file (Cameron Skinner explains in detail on his blog). The code metrics calculated are the standard ones you’d see inside Visual Studio (explanations of metric values):

    • Maintainability Index
    • Cyclomatic Complexity
    • Depth of Inheritance
    • Class Coupling
    • Lines Of Code (LOC)

    Basically, the power tool adds a Metrics.exe file to an existing Visual Studio 2010 Ultimate or Visual Studio 2010 Premium or Team Foundation Server 2010 installation.

    So what does this mean?  It means that you can now start running code metrics as part of your builds in TFS.  How?  Well, since this post is titled “The Poor Man’s Way”, I’ll show you the quick and dirty (read: it works but is not elegant) way to do it.

    As a note, Jakob Ehn describes a much more elegant way to do it, including a custom build activity, the ability to fail a build based on threshold, and better parameterization.  I really like how flexible it is!  Below is my humble, quick & dirty way.

    The below steps will add a sequence (containing individual activities to the build process workflow that will run just prior to copying binaries to the drop folder.  (These steps are based on modifying DefaultBuildTemplate.xaml.)

    1. Open the build process template you want to edit (it may be simpler to create a new template (based on the DefaultBuildProcessTemplate.xaml) to work with.
    2. Expand the activity “Run On Agent”
    3. Expand the activity “Try, Compile, Test and Associate Changesets and Work items”
      1. Click on “Variables”, find BuildDirectory, and set its scope to “Run On Agent”
    4. In the “Finally” area, expand “Revert Workspace and Copy Files to Drop Location”
    5. From the toolbox (Control Flow tab), drag a new Sequence onto the designer, just under/after the “Revert Workspace for Shelveset Builds”. (Adding a sequence will allow you to better manage/visualize the activities related to code metrics generation).
      1. In the Properties pane, set the DisplayName to “Run Code Metrics”
    6. From the toolbox (Team Foundation Build Activities), drag a WriteBuildMessage activity into the “Run Code Metrics” sequence.
      1. In the Properties pane
        1. set DisplayName to Beginning Code Metrics
        2. set Importance to Microsoft.TeamFoundation.Build.Client.BuildMessageImportance.Normal (or adjust to .High if needed)
        3. set Message to “Beginning Code Metrics: “ & BinariesDirectory
    7. From the toolbox, drag an InvokeProcess activity into the sequence below the “Beginning Code Metrics” activity (this activity will actually execute code metrics generation).
      1. In the Properties pane
        1. set DisplayName to Execute Coded Metrics
        2. set FileName to “””<path to Metrics.exe on the build machine>”””
        3. set Arguments to “/f:””” & BinariesDirectory & “\<name of assembly>”” /o:””” & BinariesDirectory & “\MetricsResult.xml”  (you can also omit the assembly name to run matrics against all assemblies found)
        4. set WorkingDirectory to BinariesDirectory
    8. (optional) From the toolbox, drag another InvokeProcess activity below “Execute Code Metrics” (This activity will copy the XSD file to the binaries directory)
      1. In the Properties pane
        1. set DisplayName to Copy Metrics XSD file
        2. set FileName to “xcopy”
        3. set Arguments to “””<path to MetricsReport.xsd>”” ””” & BinariesDirectory & “”””
    9. Save the XAML file and check it in to TFS.

    Workflow after adding code metrics sequenceThe sequence you just added should look like (boxed in red):

    You basically have a sequence called “Run Code Metrics” which first spits out a message to notify the build that code metrics are beginning.

    Next, you actually execute the Metrics.exe executable via the InvokeProcess activity, which dumps the results (XML) file in the Binaries directory (this makes it simpler to eventually copy into the drop folder).

    The “Copy Metrics XSD file” activity is another InvokeProcess activity which brings along the appropriate XSD file with the metrics result file.  This is optional of course.

    After you run a build using this updated template, your drop folder should have something like this:

    Drop folder after running build with new template

    Pay no attention to the actual binaries – it’s the presence of MetricsReport.xsd and MetricsResults.xml that matter.

    Pretty cool, but there’s one annoyance here!  The metrics results are still in XML, and aren’t nearly as readable as the results pane inside Visual Studio:

    MetricsResults.xml on top, Code Metrics Results window in VS on bottom

    Don’t get me wrong – this is a huge first step toward a fully-baked out-of-VS code metrics generator.  The actual report generation formatting will surely be improved in future iterations.

    I decided to take one additional step and write a simple parser and report generator to take the XML results and turn them into something more pretty, like HTML.

    Before I dive into code, this is the part where I remind you that I’m not (nor have I ever been) a developer by trade, so the code in this blog is purely for functional example purposes.  Winking smile

    I created a relatively simple console application to read in a results XML file, parse it, and spit out a formatted HTML file (using a style sheet to give some control over formatting).

    I’m posting the full example code to this post, but below are the highlights:

    I first created some application settings to specify the thresholds for Low and Moderate metric values (anything above ModerateThreshold is considered “good”).

    Settings to specify Low and Moderate metric thresholds

    I created a class called MetricsParser, with properties to capture the results XML file path, the path to output the report, and a path to a CSS file to use for styling.

    To store individual line item results, I also created a struct called ResultEntry:

        struct ResultEntry
        {
            public string Scope { get; set; }
            public string Project { get; set; }
            public string Namespace { get; set; }
            public string Type { get; set; }
            public string Member { get; set; }
            public Dictionary<string, string> Metrics { get; set; }
        }

    I then added:

    private List<ResultEntry> entriesShifty

    which captures each code metrics line item.

    If you look at the results XML file, you can see that in general the format cascades itself, capturing scope, project, namespace, type, then member.  Each level has its own metrics.  So I wrote a few methods which effectively recurse through all the elements in the XML file until a complete list of ResultEntry objects is built.

    private void ParseModule(XElement item)
            {
                string modulename = item.Attribute("Name").Value.ToString();
                
                ResultEntry entry = new ResultEntry
                {
                    Scope = "Project",
                    Project = modulename,
                    Namespace = "",
                    Type = "",
                    Member = ""
                };
                List<XElement> metrics = (from el in item.Descendants("Metrics").First().Descendants("Metric")
                                          select el).ToList<XElement>();
                entry.Metrics = GetMetricsDictionary(metrics);
                entries.Add(entry);
                List<XElement> namespaces = (from el in item.Descendants("Namespace")
                                          select el).ToList<XElement>();
                foreach (XElement ns in namespaces)
                {
                    ParseNamespace(ns, modulename);
                }
            }

    Bada-bing, now we have all our results parsed.  Next, to dump them to an HTML file.

    I simply used HtmlTextWriter to build the HTML, the write it to a file.  If a valid CSS file was provided, the CSS was embedded directly into the HTML header:

     #region Include CSS if available
     
                    string cssText = GetCssContent(CssFile);
                    if (cssText != string.Empty)
                    {
                        writer.RenderBeginTag(HtmlTextWriterTag.Style);
                        writer.Write(cssText);
                        writer.RenderEndTag();
                    }
     
    #endregion

    After that, I looped through my ResultEntry objects, inserting them into an HTML table, applying CSS along the way.  At the end, the HTML report is saved to disk, ideally in the build’s binaries folder.  This then allows the report to be copied along with the binaries to the TFS drop location.

    Code Metrics Results HTML Report

    You’ll notice that this layout looks much like the code metrics in Visual Studio if exported to Excel.

    So again, not the most sophisticated solution, but one that a pseudo-coder like me could figure out.  You can expand on this and build all of this into a custom build activity which would be much more portable.

    Here is the code for MetricsParser:

    Again I recommend looking at Jakob’s solution as well.  He puts a much more analytical spin on build-driven code metrics by allowing you specify your own thresholds to help pass or fail a build.  My solution is all about getting a pretty picture

    Happy developing!

  • Steve Lange @ Work

    Using Oracle and Visual Studio together?

    • 1 Comments

    It’s about to get a heck of a lot easier!

    Both of what I’m about to discuss below are in beta, so please exercise your normal caution when using these tools.

    vs2010logo

    Oracle Data Access Using Entity Framework and LINQ

    A beta of Oracle Data Access Components (ODAC) for Microsoft Entity Framework and LINQ to Entities is now available on the Oracle Technology Network (OTN). What is this? The ODAC for EF and LINQ is a set of components that bring Oracle data access into the folds of the Microsoft Entity Framework, Language Integrated Query (LINQ), and Model-First development.

    If you’ve ever used the Entity Framework or LINQ, you can readily understand how productive these capabilities can be for a developer. Previously, EF and LINQ were not feasible with Oracle.

    If you’re not familiar with EF, LINQ, or the concept of Model-First:

    • The Microsoft Entity Framework (EF) abstracts the relational, logical database schema and presents a conceptual schema to the .NET application. It provides object-relational mapping for .NET developers.
    • LINQ is a .NET data querying language which can query a multitude of data sources using common structured syntax.
    • Model-First allows the conceptual model to be created first by the developer. Next, Visual Studio can create DDL scripts to generate the relational database model based on the conceptual model.

    Get started today! Download the beta, and then walk through the tutorial.

    Note: The beta includes the 32-bit Oracle Database client 11.2, which can access Oracle Database server 9.2 and higher. It requires Microsoft Visual Studio 2010 and .NET Framework 4.

    Toad Extension for Visual Studio 2010Oracle Database Change Management with Toad Extension for Visual Studio

    Speaking of Visual Studio, did you know our friends at Quest Software have been hard at work developing the Toad Extension for Visual Studio? Toad Extension for Visual Studio is a database schema provider (DSP) for Oracle in Visual Studio 2010, and aims to give the full benefits of Visual Studio 2010’s database change management and development features to Oracle databases. This includes offline database design, development and change management, better aligning your Oracle development with the rest of your organization’s application lifecycle management methodology.

    How do you get started? Download the beta, watch a couple videos, and dive in!

     

    Links & Additional Information

    ODAC for Microsoft Entity Framework and LINQ

    Toad Extension for Visual Studio

  • Steve Lange @ Work

    Steve’s Development Tools Newsletter – April 2011

    • 0 Comments

    I receive a lot of email each week from you asking very specific, and valuable questions. It’s my hope that a newsletter like this will help me communicate important announcements, tips/tricks, and other items to help you and your team ultimately be more successful! Whenever I post a new newsletter, I will send email notifications to those of you who would like to be contacted. If you don’t want to receive email notifications, just let me know!

    Announcements

    • Happy Birthday to Visual Studio 2010!  Ah, how time flies when you’re having fun!  Check out Soma’s blog for more fun information about Visual Studio 2010’s birthday.
    • The Team Foundation Server Integration Platform (think: plumbing which can be used to build integrations/synchronizations/migrations) has been updated.  This update is primarily bug fixes, but still an important release if you’re rolling your own migration tool for TFS.  Brian Harry lists the bug fixes here.
    • Do you have lots of build definitions in TFS 2010?  Is your build node in TFS starting to look a little too lengthy/busy?  I recommend you take a look at Inmeta Build Explorer in the Visual Studio gallery.  It uses a naming convention to help visually organize your build definition into a more navigable structure
    • A new book on TFS entitled “Professional Team Foundation Server 2010” has just recently been released.   It’s a great read which goes into how to get the most out of the capabilities of TFS across the board (including customizing and extending).
    • Oracle and .NET now play even better together with Oracle’s release of the ODAC for EF and LINQ and Quest’s Toad Extension for Visual Studio.  Now you can query Oracle easily using LINQ and Entity Framework, and leverage the Toad Extension for enabling change management for the development of Oracle databases.
    • We’re making it easier for Eclipse developers to take advantage of Windows Azure with the CTP release of the Windows Azure Plugin for Eclipse.  Take a look at this blog post for more details!

    Events & Training

    MIX11 is NOW!

    If you’re not one of the lucky ones to be able to attend in person, you can still catch it live online at http://live.visitmix.com/.

    MSDN Events Presents:  Understanding Azure

    Cloud Development is one of the fastest growing trends in our industry. Don’t get left behind. In this event, Rob Bagby and Bruno Terkaly will provide an overview of developing with Windows Azure. They will cover both where and why you should consider taking advantage of the various Windows Azure’s services in your application, as well as providing you with a great head start on how to accomplish it. This half-day event will be split up into 3 sections. The first section will cover the benefits and nuances of hosting web applications and services in Windows Azure, as well as taking advantage of SQL Azure. The second section will cover the ins and outs of Windows Azure storage, while the third will illustrate the Windows Azure App Fabric.

    DATE
    CITY, STATE
    TIME
    REGISTRATION LINK
    April 15, 2011
    Tempe, AZ
    1:00 PM – 5:00 PM
    April 18, 2011
    Bellevue, WA
    1:00 PM – 5:00 PM
    April 19, 2011
    Portland, OR
    1:00 PM – 5:00 PM
    April 20, 2011
    Irvine, CA
    1:00 PM – 5:00 PM
    April 21, 2011
    Los Angeles, CA
    1:00 PM – 5:00 PM

    What Event Do You Want?

    We’re doing some initial planning for our developer & platform events in the summer and fall.  What would you like to see, especially from a development tools perspective?  Some thoughts we’re currently considering:

    • Agile Database Development
    • Lab Management
    • Architecture with Visual Studio 2010

    Let me/us know what grabs you!

    QuickAnswers

    • If you have Visual Studio Ultimate, you have access to unlimited load testing (previously your limit was 250 v-users).  You can configure multiple load agents to ramp up your load.  Any VS Ultimate user can leverage them.
    • This is a know issue in Test Manager that when building a test case if you go beyond 10 steps the steps window shrinks. This makes it harder to see multiple steps at the same time.  You can try restoring the Test Manager window from Maximize and then manually change window size.
    • When doing a schema compare, remember that the Compare Settings->Ignore Objects dialog lists items for you to check if you want to ignore them, not include them.  By default, Extended Properties are ignored (checked).
    • If you’re losing IntelliSense in database projects, it’s most commonly related to online/offline availability, insertion points, and specific conditions in the T-SQL Editor.  One way to help troubleshoot is to create a new, simple database project and see what IntelliSense experience you have.

    Final Thoughts

    Please continue to send me your ideas for items to include in this monthly newsletter.  Some have requested more information about the different roles in the developer & platform evangelism (DPE) division at Microsoft, which I’m happy to do!

    Others have inquired about the best way to reach me to ask simple, one-off questions.  While direct email is always fine, I do also use Formspring, a question and answer service.  You can find my profile page on Formspring (and ask me a question) here:  http://www.formspring.me/slange.

Page 1 of 1 (3 items)