Monday, October 30, 2006

 

Video Recommendations


Monday, October 23, 2006

 

Credit where credit is due

Weird Al's new album, Straight Outta Lynwood, has landed on Billboard's top 10, with its premier song, White and Nerdy, getting number 9. Both marks are the artist's highest showings in his 27 year career. The White and Nerdy music video "world premier" on AOL was canceled because it was already widely distributed on YouTube and other video sharing sites. Rather than being miffed, Weird Al gives the Internet credit for his greatest success, saying,
The ("Nerdy") video has gotten a lot of attention, and the proliferation of places like YouTube (has) been a big help.

I'd kind of written off the chance of ever having another hit single, since record labels weren't really releasing commercial ones. As much as people are griping about the Internet taking sales away from artists, it's been a huge promotional tool for me.


Friday, October 20, 2006

 

It's not tool use, but...

Most impressive. One or more crows in Japan have learned that an easier way to crack a nut is to drop it into traffic. That left the subtle problem of having to retrieve the nut guts from amongst the wizzing cars. Watch the video to see the amazing solution.

From Ursi's Blog


Tuesday, October 17, 2006

 

Quote o' the Day

On today's All Things Considered, NPR's Scott Horsley reported on Bargain-Hunting in San Diego's Real-Estate Slump. He interviewed real estate auctioneer Bill Shepner, who offered this gem.
If you're looking for the next foreclosure, follow the Hummer. A lot of these Hummers were paid for out of equity lines and refinances -- and the Lexuses and the Mercedes.

Their income maybe was never enough to afford the loans, and their adjustable-rate mortgages are kicking in, and there's going to be some blood flowing in the streets.


Sunday, October 15, 2006

 

Free the podcasts

Two of my favorite NPR shows just announced that they'd start offering free podcasts. Previously, This American Life and Marketplace Money shows were available as podcasts from audible.com for a fairly hefty fee; to subscribe to Marketplace Money for a year cost nearly $120, whereas becoming a member of my local NPR station cost $20. Now they're available for the incredibly low price of "donate or feel guilty." Interestingly, at least TAL is following the New York Times model of moving the free content to a fee-required archive after a bit. I'll probably only use the Marketplace Money feed because it publishes new content earlier than YPR streams it, while TAL publishes after I've already created my own podcast of the content from YPR.

Saturday, October 14, 2006

 

Memory about Storage

I remember that before serious Internet access reached the small town I grew up in, there was a sundry electronic goods store there that would mail order computer parts. For some reason, I stopped there one day and asked them about computer component prices, even though I had neither sufficient disposable income to purchase or a computer new enough to support such items. I remember being shocked that they were charging in the neighborhood of $2.50 per MB of hard drive storage, when the going rate should've been closer to $1 per MB.

I tell this "back in my day, uphill both ways" story only because I think it's wonderful that roughly 12 years later hard drive storage can be purchased at about $0.25 per GB, according to recent postings on SlickDeals. That's a 10,000 times increase in value compared to the price the local shop offered years ago, an annualized improvement of about 115%. Of course, those numbers are at least as suspect as my "through two feet of snow, barefoot" memory.


Wednesday, October 11, 2006

 

Integrating FxCop into CruiseControl.NET

Recently, I needed to integrate FxCop into our CC.NET server.  I had a few design goals for the integration.
I found couple useful resources along the way:
I discovered fairly quickly that FxCop locks the assemblies that it's analyzing, which meant that I had to make a copy of the assemblies that FxCop was analyzing or else the build project would fail because it couldn't copy to its output directory.  I also discovered that the return value of FxCopCmd doesn't indicate whether rule violations were found, rather whether a catastrophic error was encountered.  That meant that to get the CC.NET build to break, I had to run FxCop from another application to control the value that was returned to CC.NET.  I decided to accommodate both of those needs with msbuild.  I could've used NAnt for the same purpose.  Specifically, to break the CC.NET build I needed msbuild to examine the FxCop output and return a failing error code if any violations were found.  The ability to parse an XML file isn't in the base functionality of msbuild; however,  the <XmlRead> task of MSBuild Community Tasks Project does have that ability.

The steps for my msbuild script are:

<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="RunCheck" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
  <!-- Required Import to use MSBuild Community Tasks -->
  <Import Project="$(MSBuildExtensionsPath)\MSBuildCommunityTasks\MSBuild.Community.Tasks.Targets"/>

  <Target Name="RunCheck">
    <CallTarget Targets="Copy" />
    <CallTarget Targets="Check" />
    <CallTarget Targets="Report" />
  </Target>

  <Target Name="RunFxCopUI">
    <CallTarget Targets="Copy" />
    <Exec Command="attrib +R $(FxCopProject)" />
    <Exec Command='"$(FxCopExe)" $(FxCopProject)'/>
  </Target>

  <Target Name="Copy">
    <Copy SourceFiles="@(DllsAndPdbs)" DestinationFolder="$(FxCopWorkDirectory)" SkipUnchangedFiles="true"/>
  </Target>

  <Target Name="Check">
    <Exec Command='"$(FxCopCmdExe)" /project:$(FxCopProject) /out:$(FxCopOutput) /directory:$(FxCopWorkDirectory) /forceoutput' />
  </Target>

  <Target Name="Report">
    <XmlRead ContinueOnError="True" XmlFileName="$(FxCopOutput)" XPath="string(count(//Issue[@Level='CriticalError']))">
      <Output TaskParameter="Value" PropertyName="FxCopCriticalErrors" />
    </XmlRead>
    <XmlRead ContinueOnError="True" XmlFileName="$(FxCopOutput)" XPath="string(count(//Issue[@Level='Error']))">
      <Output TaskParameter="Value" PropertyName="FxCopErrors" />
    </XmlRead>
    <XmlRead ContinueOnError="True" XmlFileName="$(FxCopOutput)" XPath="string(count(//Issue[@Level='CriticalWarning']))">
      <Output TaskParameter="Value" PropertyName="FxCopCriticalWarnings" />
    </XmlRead>
    <XmlRead ContinueOnError="True" XmlFileName="$(FxCopOutput)" XPath="string(count(//Issue[@Level='Warning']))">
      <Output TaskParameter="Value" PropertyName="FxCopWarnings" />
    </XmlRead>

    <Math.Add Numbers="$(FxCopCriticalErrors);$(FxCopErrors);$(FxCopCriticalWarnings);$(FxCopWarnings)">
      <Output TaskParameter="Result" PropertyName="FxCopRuleViolations" />
    </Math.Add>

    <Error Text="FxCop encountered $(FxCopRuleViolations) rule violation(s). Critical errors: $(FxCopCriticalErrors). Errors: $(FxCopErrors). Critical warnings: $(FxCopCriticalWarnings). Warnings: $(FxCopWarnings)."
Condition="$(FxCopRuleViolations) &gt; 0" />
  </Target>

  <ItemGroup>
    <DllsAndPdbs Include="..\..\..\ThirdParty\lib\*.dll;bin\debug\*.dll;bin\debug\*.pdb;"/>
  </ItemGroup>

  <PropertyGroup>
    <FxCopWorkDirectory>FxCop</FxCopWorkDirectory>
    <FxCopProject>ProjectName.FxCop</FxCopProject>
    <FxCopOutput>$(FxCopWorkDirectory)\ProjectName.FxCop.output.xml</FxCopOutput>
  </PropertyGroup>

  <ItemGroup>
    <OutputFiles Include="FxCop\*.dll;FxCop\*.pdb" />
  </ItemGroup>

  <PropertyGroup>
    <FxCopCriticalErrors>0</FxCopCriticalErrors>
    <FxCopErrors>0</FxCopErrors>
    <FxCopCriticalWarnings>0</FxCopCriticalWarnings>
    <FxCopWarnings>0</FxCopWarnings>
  </PropertyGroup>

  <PropertyGroup>
    <ExpectedFxCopCmdPath>C:\Program Files\Microsoft FxCop 1.35\FxCopCmd.exe</ExpectedFxCopCmdPath>
  </PropertyGroup>

  <Choose>
    <When Condition="Exists($(ExpectedFxCopCmdPath))">
      <!-- Hope that the expected version of FxCop is installed -->
      <PropertyGroup>
        <FxCopCmdExe>$(ExpectedFxCopCmdPath)</FxCopCmdExe>
      </PropertyGroup>
    </When>
    <Otherwise>
      <!-- Otherwise hope that FxCop is in the path. -->
      <PropertyGroup>
        <FxCopCmdExe>fxcopcmd.exe</FxCopCmdExe>
      </PropertyGroup>
    </Otherwise>
  </Choose>
</Project>

To get the output of FxCop to appear on the CC.NET dashboard, I needed to tell FxCop to write its output to a file.  Use the "/out:<filename>" switch for that.  The "/forceoutput" switch is also nice because it causes an output file to be written even if no rules are violated.  Then I needed to merge that into the CC.NET build log.  The CC.NET merge task is intended for that.  The gotcha I discovered is that I needed to put the <merge> task under the <publishers> tag, not the <tasks> tag.  If it's under <tasks>, it's not executed if the build fails, which foils my goal of getting the rule violations onto the CC.NET dashboard.

That leaves only the question of how to cause the FxCop CC.NET project to run after the main project completes successfully.  CC.NET includes a <projectTrigger>, which is perfect for this task.  Not only is the project trigger able to run the dependent project only when the parent project completes successfully, but it also is smart enough not to run the dependent project multiple times if the parent project completes while the child is still running.  Here's my ccnet.config:

<cruisecontrol>
  <project name="FxCop">
    <publishExceptions>true</publishExceptions>
    <triggers>
      <projectTrigger project="ParentProject">
        <triggerStatus>Success</triggerStatus>
      </projectTrigger>
    </triggers>
    <tasks>
      <msbuild>
        <timeout>1800</timeout>
        <executable>C:\Windows\Microsoft.NET\Framework\v2.0.50727\msbuild.exe</executable>
        <projectFile>ProjectFile.Fxcop.msbuild.xml</projectFile>
        <buildArgs>/noconsolelogger /v:diag</buildArgs>
        <logger>ThoughtWorks.CruiseControl.MsBuild.XmlLogger,ThoughtWorks.CruiseControl.MsBuild.dll</logger>
      </msbuild>
    </tasks>
    <publishers>
      <merge>
        <files> <file>FxCop\ProjectName.FxCop.output.xml</file> </files>
      </merge>
      <xmllogger />
    </publishers>
  </project>
</cruisecontrol>
My biggest disappointment with the result is that I couldn't get the detailed FxCop results to appear on the CC.NET web dashboard page for each build; rather they appear on the "FxCop Report" page, which I decided was not worth the effort to change.  However, I really didn't like the look of the standard report, so I edited my CruiseControl\webdashboard\dashboard.config file to use Brian Likes's XSL.

Tuesday, October 10, 2006

 

Respectful Protest

If you're going to burn the neighboring country's flag, you can at least do it in a nice shirt and tie, as modeled by this protesting Korean.

Image swiped from cnn.com.

Monday, October 02, 2006

 

Random Coolness


Sunday, October 01, 2006

 

Quote o' the Day

NPR's Bob Mondello reviewed The Queen on Saturday's ATC. His synopsis included the following brilliant exchange betwen Elizabeth II and the newly elected Prime Minister Blair.
HM QE II: Have we shown you how to start a nuclear war, yet?
Tony Blair: Ah, no.
HM QE II: Oh, first thing we do appearantly...
Tony Blair: You obviously know my job better than I do.
HM QE II: Yes. Well, you are my tenth Prime Minister, Mr. Blair. My first, of course, was Winston Churchill.

Mondello: How's that for putting a man in his place?


This page is powered by Blogger. Isn't yours?