• Announcing Gemcutter/Caliper integration

    by Ben

    We're extremely happy to announce that Caliper is now generating metrics for all gems pushed to Gemcutter!

    By taking advantage of the new webhooks feature in Gemcutter, Caliper is alerted whenever a new version of a gem is pushed. At that point, we automatically generate metrics. In addition, every gem page on Gemcutter now features a 'Metrics' link to the Caliper metrics.

    metrics_link

    We're thrilled to be generating metrics for so many great Ruby projects. As always, please send us feedback about how we can improve Caliper!

    For more details on webhooks, check out the Changelog screencast by Nick Quaranto.

    Many, many thanks to Nick Quaranto, Chad Fowler, and all the other supremely awesome Gemcutter contributors!

    Devver Caliper: Hosted metric_fu for your Ruby project.
    Get set up in under a minute

    Posted on February 2nd, 2010 by Ben in Uncategorized and tagged , , .

  • Help us improve Caliper by taking a short survey

    by Ben

    If you have tried Caliper, it would help us immensely if you filled out this short, eight-question survey at Survey.io. Thanks!

    Devver Caliper: Hosted metric_fu for your Ruby project.
    Get set up in under a minute

    Posted on January 25th, 2010 by Ben in Uncategorized and tagged , .

  • Avdi Grimm on Confident Code

    by Dan

    Recently Avdi, gave a talk on Confident Code at B’More on Rails. I enjoyed the talk and recommend giving it a listen, if you are interested in better structured code. The slides are available here, if you want to follow along.

    Avdi Grimm on Confident Code at B'More on Rails from Avdi Grimm on Vimeo.

    Devver Caliper: Hosted metric_fu for your Ruby project.
    Get set up in under a minute

    Posted on January 20th, 2010 by Dan in Uncategorized.

  • Upcoming improvements for Caliper

    by Ben

    For the past several weeks, you may have noticed that not much has changed on Caliper. The reason for this is that we've been working hard to allow you to use Caliper on your private GitHub repositories (we're currently in private beta for that feature. If you are interested, you can sign up for a beta invitation).

    However, we realize that we have much to improve on Caliper. We've been talking with our users to identify the biggest problems and most-requested features. In addition, we're getting help from the folks at Viget Labs to make Caliper easier to understand, more intuitive to use, and all around better.

    In our first batch of work, we'll be focusing on three improvements.

    First, we'll be developing an improved project dashboard. Our current dashboard isn't terribly useful. We'd like to better represent the state of the project, important trends, and areas that need the most help. We're working now to come up with a concrete design that addresses these issues. In the meantime, what data would you find most helpful on the dashboard?

    We'll also be changing the way you navigate to specific tools. Users have told us that the specific tool names ('Reek', 'Flog') are not, by themselves, very helpful for navigation. As a result, we'll be increasingly highlighting their function. For example, even if you aren't familiar with Flog, we'll make it obvious that it is a tool for measuring complexity.

    We're considering eventually merging tools that have a similar function. So instead of going to two different pages for Reek and Roodi results, we might just have a 'code smells' report. Similarly, Flog and Saikuro might be presented within the same page. Would this be helpful?

    To be clear, it isn't our intention to obscure the fact that Caliper is built on great tools like metric_fu, Reek, Flog, etc. We will still make it easy to understand where the data is coming from and highlight the work being done by the dedicated open-source developers who write them. However, we think that grouping by function will make Caliper easier to use and understand.

    Did you know that you can set up Caliper to automatically generate metrics using GitHub post-receive hooks? Did you know that, by default, up to 15 of your latest commits are automatically run through Caliper when you set up a project? Or that with one click, you can generate metrics for up to 40 commits throughout the history of your project?

    Many users don't know this, because our UI for these features is currently pretty terrible. The last task in the current batch of work will be to make these features more visible and easier to use. Our goal is to make it simple to see trends in your project over time.

    (Incidentally, many users also don't know that you can view a metrics diff for two commits to see how a commit has changed the metrics, but making this more noticeable may or may not get tackled in the first set of changes).

    What's next for Caliper after we complete these changes? We're currently talking to users about what features and improvements matter most to them. One possibility is to display some or all of our metric data directly on a view of source code itself, so you don't have to open up an editor (or click through to GitHub) to see the code. How important is this feature to you?

    As always, feedback from our users is hugely helpful. If you have ideas about features that you'd like to see, please let us know in the comments or start a discussion at our support site. Thanks!

    Devver Caliper: Hosted metric_fu for your Ruby project.
    Get set up in under a minute

    Posted on January 14th, 2010 by Ben in Uncategorized and tagged , .

  • Churn, a gem for class and method level churn rates

    by Dan

    There are many metrics that can help identify potentially problematic code. One metric that has a high correlation with buggy code is high-churn code.

    Code churn metrics were found to be among the most highly correlated with problem reports

    -- Predicting Bugs from History, Microsoft Research

    Through metric_fu, Ruby devs have had access to information about high-churn files, but that is a bit too high level. Often with Rails apps the few controllers you have bubble up to the top, as do your most commonly edited model files. Often this isn't because old code is being modified and fixes being applied, often it is new features and methods are being added. What you really want to find is the classes and methods that seem to require updates every time the code is changed. Often this means a method needs to be refactored as it is doing too much, and is tightly coupled with many other parts of the code. If code is changing to often it is likely to be violating the Single Responsibility Principle.

    Martin defines a responsibility as a reason to change, and concludes that a class or module should have one, and only one, reason to change.

    -- Wikipedia, Single Responsibility Principle

    In our own projects we have noticed this and sometimes recognized the problem. Often this leads to a bit of refactoring which separates the code in more logical and easier to debug and test pieces. Often though we haven't noticed until many bugs keep popping up in the same area of the application. If there were a tool to identify these areas of the code base before a single person on the team notices the problem that would be great. Well, now with our Churn gem you can.

    Churn analyzes each commit to your Git repo and notes which files, classes, and methods were changed. If you run Churn over a series of commits it will begin to build up a list of the highest churn classes and methods (it can always give you the high-churn files, since it can get that straight from Git log with no analysis). Currently the gem is just set up to output the information to the command line. Once we finish up a bit more testing it will be integrated into metric_fu, as well as Caliper. On Caliper it will be easy to go back and generate the current high-churn methods and classes for the projects history.

    Give it a shot on your projects, and let me know if there are any feature requests, bugs, or problems. I hope this helps identify some places you can improve your projects.

    Instructions:

    > gem install churn
    > cd PROJECT_ROOT_DIRECTORY
    > churn

    example output:

    **********************************************************************
    * Revision Changes
    **********************************************************************
    files:
     * "lib/churn/churn_calculator.rb"
    
    classes:
     * {"klass"=>"ChurnCalculator", "file"=>"lib/churn/churn_calculator.rb"}
    
    methods:
     * {"klass"=>"ChurnCalculator", "method"=>"ChurnCalculator#calculate_revision_data", "file"=>"lib/churn/churn_calculator.rb"}
     * {"klass"=>"ChurnCalculator", "method"=>"ChurnCalculator#filters", "file"=>"lib/churn/churn_calculator.rb"}
     * {"klass"=>"ChurnCalculator", "method"=>"ChurnCalculator#display_array", "file"=>"lib/churn/churn_calculator.rb"}
     * {"klass"=>"ChurnCalculator", "method"=>"ChurnCalculator#initialize", "file"=>"lib/churn/churn_calculator.rb"}
    **********************************************************************
    * Project Churn
    **********************************************************************
    files:
     * {:file_path=>"lib/churn/churn_calculator.rb", :times_changed=>13}
     * {:file_path=>"README.rdoc", :times_changed=>7}
     * {:file_path=>"lib/tasks/churn_tasks.rb", :times_changed=>6}
     * {:file_path=>"Rakefile", :times_changed=>5}
     * {:file_path=>"VERSION", :times_changed=>4}
     * {:file_path=>"lib/churn/git_analyzer.rb", :times_changed=>4}
     * {:file_path=>"test/test_helper.rb", :times_changed=>4}
     * {:file_path=>"test/unit/churn_calculator_test.rb", :times_changed=>3}
     * {:file_path=>"test/churn_test.rb", :times_changed=>3}
    
    classes:
     * {"klass"=>{"klass"=>"ChurnCalculator", "file"=>"lib/churn/churn_calculator.rb"}, "times_changed"=>9}
     * {"klass"=>{"klass"=>"LocationMapping", "file"=>"lib/churn/location_mapping.rb"}, "times_changed"=>1}
     * {"klass"=>{"klass"=>"GitAnalyzer", "file"=>"lib/churn/git_analyzer.rb"}, "times_changed"=>1}
     * {"klass"=>{"klass"=>"ChurnTest", "file"=>"test/churn_test.rb"}, "times_changed"=>1}
     * {"klass"=>{"klass"=>"ChurnCalculatorTest", "file"=>"test/unit/churn_calculator_test.rb"}, "times_changed"=>1}
    
    methods:
     * {"method"=>{"klass"=>"ChurnCalculator", "method"=>"ChurnCalculator#initialize", "file"=>"lib/churn/churn_calculator.rb"}, "times_changed"=>3}
     * {"method"=>{"klass"=>"ChurnCalculator", "method"=>"ChurnCalculator#to_h", "file"=>"lib/churn/churn_calculator.rb"}, "times_changed"=>3}
     * {"method"=>{"klass"=>"ChurnCalculator", "method"=>"ChurnCalculator#analyze", "file"=>"lib/churn/churn_calculator.rb"}, "times_changed"=>2}
     * {"method"=>{"klass"=>"ChurnCalculator", "method"=>"ChurnCalculator#report", "file"=>"lib/churn/churn_calculator.rb"}, "times_changed"=>2}
     * {"method"=>{"klass"=>"ChurnCalculator", "method"=>"ChurnCalculator#display_array", "file"=>"lib/churn/churn_calculator.rb"}, "times_changed"=>2}
     * {"method"=>{"klass"=>"ChurnCalculator", "method"=>"ChurnCalculator#calculate_revision_data", "file"=>"lib/churn/churn_calculator.rb"}, "times_changed"=>2}
     * {"method"=>{"klass"=>"ChurnCalculator", "method"=>"ChurnCalculator#emit", "file"=>"lib/churn/churn_calculator.rb"}, "times_changed"=>1}
     * {"method"=>{"klass"=>"ChurnCalculator", "method"=>"ChurnCalculator#calculate_revision_changes", "file"=>"lib/churn/churn_calculator.rb"}, "times_changed"=>1}
     * {"method"=>{"klass"=>"ChurnCalculator", "method"=>"ChurnCalculator#get_changes", "file"=>"lib/churn/churn_calculator.rb"}, "times_changed"=>1}
     * {"method"=>{"klass"=>"ChurnCalculator", "method"=>"ChurnCalculator#calculate_changes!", "file"=>"lib/churn/churn_calculator.rb"}, "times_changed"=>1}
     * {"method"=>{"klass"=>"ChurnCalculator", "method"=>"ChurnCalculator#set_source_control", "file"=>"lib/churn/churn_calculator.rb"}, "times_changed"=>1}
     * {"method"=>{"klass"=>"GitAnalyzer", "method"=>"GitAnalyzer#date_range", "file"=>"lib/churn/git_analyzer.rb"}, "times_changed"=>1}
    

    Visit Churn on github, and view the current Churn metrics.

    Devver Caliper: Hosted metric_fu for your Ruby project.
    Get set up in under a minute

    Posted on January 12th, 2010 by Dan in Uncategorized.

  • Announcing DataMapper/SimpleDB Adapter 1.0.0

    by Avdi

    Today we are pleased to announce the release of dm-adapter-simpledb 1.0.0.

    The big new feature is compatibility with DataMapper 0.10.*. The DataMapper adapter API changed significantly in 0.10, necessitating a broad rewrite. This release breaks backwards compatibility with DataMapper 0.9.*.

    In addition, the way nils are stored has changed, so datasets created with the 0.9.* adapter may need to be updated. Previously nils were stored in the form of a special nil value (by default, the string "nil"). Starting with version 1.0.0, any attributes set to nil will be removed from the SimpleDB record. This is more in line with the SimpleDB concept of NULL, and enables IS NOT NULL predicates to work as expected.

    New and existing SimpleDB adapter features include:

    • NEW: Supports all DataMapper query predicates.
    • NEW: DataMapper identity map support for record caching
    • NEW: Lazy-loaded attributes
    • NEW: DataMapper Serial property support via UUIDs.
    • Uses the RightAWS gem for efficient SimpleDB operations.
    • Full set of CRUD operations
    • Can translate many queries into efficient native SELECT operations.
    • Migrations
    • Array properties
    • Basic aggregation support (Model.count("..."))
    • String "chunking" permits attributes to exceed the 1024-byte limit

    If you have Gemcutter in your Gem sources, you can install the gem immediately:

    gem install dm-adapter-simpledb
    

    Check out the code at http://github.com/devver/dm-adapter-simpledb. You can see metrics for the code here. Give it a try, and feel free to send us any feedback, patches, and suggestions. The project's issue tracker is on GitHub, or you can always email us.

    Devver Caliper: Hosted metric_fu for your Ruby project.
    Get set up in under a minute

    Posted on November 16th, 2009 by Avdi in Uncategorized and tagged , .

  • Beware of pipe duplication in subprocesses

    by Avdi

    I've been writing a lot lately about managing subprocesses in Ruby, and in that vein I thought I'd write up an interesting subprocess gotcha we encountered recently.

    I won't go into the details of how we discovered the issue, except to say that it manifested when using the Main and Servolux gems (both of which I highly recommend) together to start daemon processes. The problem can be boiled down to this brief snippet, distilled by Tim Pease:

    ruby -e 'IO.popen("ruby -e \"STDOUT.dup; STDOUT.close; sleep\"").read
    

    If you try to execute that line, the #read will hang indefinitely, even though STDOUT was closed in the child process. Why? Tim explains:

    "...the parent script will block waiting for pipe to close in the child process. However, because there is a duplicate of the STDOUT file descriptor in the child, both must be closed or the parent will never unblock from the read. [...] ALL file descriptors have to be closed before an EOF is sent through the pipe to the parent. Hence, the read will never return."

    The moral of this story: don't try to read from a subprocess which duplicates STDOUT or STDERR handles. Or if you do, take precautions by using calls which don't wait for an EOF - such as #readpartial - instead of #read.

    I can take no credit for solving this one. All the honor goes to Ara T. Howard, who expended much mental energy and beer to get to the bottom of the problem; and Tim Pease, who neatly summarised the issue and explained it in terms that even I could understand. I'm documenting it here in case anyone else runs into it.

    Devver Caliper: Hosted metric_fu for your Ruby project.
    Get set up in under a minute

    Posted on October 22nd, 2009 by Avdi in Uncategorized and tagged , , , , , , .

  • Devver client 2.4.2 is released

    by Ben

    We've just released version 2.4.2 of our new client. This release fix some bugs that you may have run into if you're just getting started on Devver.

    Important Changes

    The biggest fixes are in the default install_dependencies hook (located in .devver/hooks/install_dependencies). The old default hook failed to install Rails correctly, so you may have repeatedly seen an error like this:

    Missing the Rails 2.3.3 gem. Please `gem install -v=2.3.3 rails`, update your RAILS_GEM_VERSION setting in config/environment.rb for the Rails version you do have installed, or comment out RAILS_GEM_VERSION to use the latest version installed.
    

    In addition, the default hook now runs rake gems:install RAILS_ENV=test instead of rake gems:install to ensure that any gems declared in config/environments/test.rb get installed.

    Updating your hook

    If you have not altered your install_dependencies hook, you can just do the following to get the new behavior:

    rm .devver/hooks/install_dependencies
    devver --init
    

    If you have altered this file, you'll need to do the following to get the new behavior:

    mv .devver/hooks/install_dependencies .devver/hooks/install_dependencies.mine
    devver --init
    

    Then port your project-specific changes from install_dependencies.mine to install_dependencies.

    As always, if you have any problems, please don't hesitate to let us know by emailing support@devver.net.

    Devver Caliper: Hosted metric_fu for your Ruby project.
    Get set up in under a minute

    Posted on September 9th, 2009 by Ben in Uncategorized.

  • Devver is headed to Lone Star Ruby Conf!

    by Ben

    Our very own Dan Mayer will be at Lone Star Ruby Conf Friday and Saturday! Be sure to talk to Dan about Devver, testing, or anything else!

    Devver Caliper: Hosted metric_fu for your Ruby project.
    Get set up in under a minute

    Posted on August 27th, 2009 by Ben in Uncategorized and tagged .

  • We’re hiring!

    by Ben

    We're looking for an awesome Ruby developer to join our team. Get more details at http://devver.net/jobs.

    Devver Caliper: Hosted metric_fu for your Ruby project.
    Get set up in under a minute

    Posted on June 15th, 2009 by Ben in Uncategorized and tagged .