tag:blogger.com,1999:blog-82562607066216452382024-02-20T03:06:54.755-05:00BigPigVTBigPigVThttp://www.blogger.com/profile/13822643534037160541noreply@blogger.comBlogger67125tag:blogger.com,1999:blog-8256260706621645238.post-49969280810046207222016-11-07T13:06:00.002-05:002016-11-07T13:08:13.738-05:00Delivering files using NuGet 2 so they're copied to the output directoryI recently had a situation where a NuGet package I was creating had to deliver some supporting DLLs which needed to be copied to the output directory (actually into a sub-directory named <span style="font-family: "courier new" , "courier" , monospace;">/x86</span>). We're using NuGet 2 at work because our internal NuGet feed is managed via ProGet, <a href="http://inedo.com/support/questions/3702" target="_blank">which doesn't yet support NuGet 3.x</a>. While <a href="https://docs.nuget.org/ndocs/schema/nuspec#using-the-contentfiles-element-for-content-files" target="_blank">NuGet 3.3+ gives the <span style="font-family: "courier new" , "courier" , monospace;">copyToOutput</span> option</a> to have content files delivered to the output directory, there's no such support in NuGet 2. In researching how to do this I came across two very helpful posts on StackOverflow which gave me the direction I needed. The posts were <a href="http://stackoverflow.com/a/30386836/123147">http://stackoverflow.com/a/30386836/123147</a> and <a href="http://stackoverflow.com/a/30316946/123147">http://stackoverflow.com/a/30316946/123147</a>.<br />
<br />
The approach I took was to have the files I needed to distribute be included in the NuGet package in the <span style="font-family: "courier new" , "courier" , monospace;">/build</span> folder, as opposed to <span style="font-family: "courier new" , "courier" , monospace;">/content</span>. In fact, I put them in a sub-folder named <span style="font-family: "courier new" , "courier" , monospace;">/x86</span> which was the desired target location in the output directory. I then used an MSBuild targets file to mark all the files in that sub-folder as always needing to be copied to the output directory. I had not worked with MSBuild targets (or properties) files before - so this approach was totally new to me.<br />
<br />
This blog post seeks to expand on using a MSBuild targets file in a NuGet package. The NuGet <a href="https://docs.nuget.org/ndocs/create-packages/creating-a-package#including-msbuild-props-and-targets-in-a-package" target="_blank">documentation talks about this technique</a> - but I thought a more step-by-step set of instructions might help others.<br />
<br />
The sample code I'm providing in this post is a little different from what I did at work in that there's no sub-folder created in the target directory. I am using a sub-folder in the NuGet package's <span style="font-family: "courier new" , "courier" , monospace;">/build</span> folder, though, so don't have to act on each file individually.<br />
<br />
<h2>
The sample scenario</h2>
The contrived example for this post is to create a package which delivers files to the output directory of any project that installs my <span style="font-family: "courier new" , "courier" , monospace;"><b>NeededFiles</b></span> package; an image and a readme file.<br />
<br />
<h2>
What does an MSBuild targets file do?</h2>
<div>
If you were to open a Visual Studio project file (e.g. csproj or vbproj) in a text editor you would see it's an XML format which defines properties and actions (i.e. "targets"). I found it pretty similar to a NANT script. What a targets file lets us do is define a target that can be imported into the project file later. The NuGet documentation explains that when a package includes a targets file with the same name as the package in its <span style="font-family: "courier new" , "courier" , monospace;">/build</span> folder the NuGet installation will add an <span style="font-family: "courier new" , "courier" , monospace;">import</span> element to the project file.<br />
<br />
<h2>
What's in the NeededFiles package?</h2>
The <span style="font-family: "courier new" , "courier" , monospace;">NeededFiles.nuspec</span> file looks like this:<br />
<span style="font-family: "courier new" , "courier" , monospace;">1. <?xml version="1.0"?></span><br />
<span style="font-family: "courier new" , "courier" , monospace;">2. <package ></span><br />
<span style="font-family: "courier new" , "courier" , monospace;">3. <metadata></span><br />
<span style="font-family: "courier new" , "courier" , monospace;">4. <id>NeededFiles</id></span><br />
<span style="font-family: "courier new" , "courier" , monospace;">5. <version>1.0.0</version></span><br />
<span style="font-family: "courier new" , "courier" , monospace;">6.</span><span style="font-family: "courier new" , "courier" , monospace;"> </span><span style="font-family: "courier new" , "courier" , monospace;"><authors>@Rob_Hale_VT</authors></span><br />
<span style="font-family: "courier new" , "courier" , monospace;">7. <requireLicenseAcceptance>false</requireLicenseAcceptance></span><br />
<span style="font-family: "courier new" , "courier" , monospace;">8. <description></span><br />
<span style="font-family: "courier new" , "courier" , monospace;">9. <span class="Apple-tab-span" style="white-space: pre;"> </span> An example of delivering files to the consuming project's output via build targets</span><br />
<span style="font-family: "courier new" , "courier" , monospace;">10. <span class="Apple-tab-span" style="white-space: pre;"> </span></description></span><br />
<span style="font-family: "courier new" , "courier" , monospace;">11. <releaseNotes>Created</releaseNotes></span><br />
<span style="font-family: "courier new" , "courier" , monospace;">12. <copyright>Copyright 2016</copyright></span><br />
<span style="font-family: "courier new" , "courier" , monospace;">13. <tags>Demo</tags></span><br />
<span style="font-family: "courier new" , "courier" , monospace;">14. </metadata></span><br />
<span style="font-family: "courier new" , "courier" , monospace;">15. <files></span><br />
<span style="font-family: "courier new" , "courier" , monospace;">16. <span class="Apple-tab-span" style="white-space: pre;"> </span><span style="color: green;"><!-- In this instance, the file(s) to be delivered are in the sub-folder named "howdy" --></span></span><br />
<span style="font-family: "courier new" , "courier" , monospace;">17. <span class="Apple-tab-span" style="white-space: pre;"> </span><file src="howdy\*.*" target="build\howdy" /></span><br />
<span style="font-family: "courier new" , "courier" , monospace;">18. <span class="Apple-tab-span" style="white-space: pre;"> </span></span><br />
<span style="font-family: "courier new" , "courier" , monospace;">19. <span class="Apple-tab-span" style="white-space: pre;"> </span><span style="color: green;"><!-- The targets file must have the same name as this package --></span></span><br />
<span style="font-family: "courier new" , "courier" , monospace;">20. <span class="Apple-tab-span" style="white-space: pre;"> </span><span style="color: green;"><!-- More info: https://docs.nuget.org/ndocs/create-packages/creating-a-package#including-msbuild-props-and-targets-in-a-package --></span></span><br />
<span style="font-family: "courier new" , "courier" , monospace;">21. <span class="Apple-tab-span" style="white-space: pre;"> </span><file src="NeededFiles.targets" target="build" /></span><br />
<span style="font-family: "courier new" , "courier" , monospace;">22 . </files></span><br />
<span style="font-family: "courier new" , "courier" , monospace;">23. </package></span><br />
<br />
The key lines for what I'm doing are 15 - 22, where the <span style="font-family: "courier new" , "courier" , monospace;">files</span> element is defined. On line 17 I'm added all the contents of a folder called "howdy" to the <span style="font-family: "courier new" , "courier" , monospace;">/build/howdy</span> target folder. This folder contains the image and readme file I want to have delivered<br />
<br />
Additionally, line 21 adds the <span style="font-family: "courier new" , "courier" , monospace;">NeededFiles.targets</span> file to the <span style="font-family: "courier new" , "courier" , monospace;">/build</span> target folder.</div>
<h3>
</h3>
<h3>
What does the NeededFiles.targets file do?</h3>
<div>
Now that the <b><span style="font-family: "courier new" , "courier" , monospace;">NeededFiles</span></b> package includes the <span style="font-family: "courier new" , "courier" , monospace;">/build/NeededFiles.targets</span> file we can take a look at what it does.</div>
<pre><span style="font-family: "courier new" , "courier" , monospace;">1. <Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
2. <ItemGroup>
3. <NativeLibs Include="$(MSBuildThisFileDirectory)howdy\*.*" />
4. <None Include="@(NativeLibs)">
5. <Link>%(RecursiveDir)%(FileName)%(Extension)</Link>
6. <CopyToOutputDirectory>Always</CopyToOutputDirectory>
7. </None>
8. </ItemGroup>
9. </Project></span></pre>
<br />
This file is imported by the consuming project. This means when the project is built line 3 declares an element named <span style="font-family: "courier new" , "courier" , monospace;">NativeLibs</span> which is comprised of the contents of the howdy folder (delivered as part of the NeededFiles package). Lines 4 - 7 are acting like a loop, instructing MSBuild to mark each file in NativeLibs so they are always copied to the output directory.<br />
<br />
If I wanted the files to all appear in a sub-folder of the output directory I could modify line 5 to be:<br />
<pre><span style="font-family: "courier new" , "courier" , monospace;"><Link>%(RecursiveDir)<span style="color: red;">howdy/</span>%(FileName)%(Extension)</Link></span></pre>
<pre><span style="font-family: "courier new" , "courier" , monospace;">
</span></pre>
<h2>
Summary</h2>
At this point the package will deliver the contents of the Howdy folder to the output directory of any project that installs the <b><span style="font-family: "courier new" , "courier" , monospace;">NeededFiles</span></b> package. Unlike files marked as content, the files in the build target folder don't even appear in the Solution Explorer in Visual Studio. "It just works."<br />
<br />
The source for my contrived example, NeededFiles, can be found at https://github.com/robhalevt/NeededFilesExampleBigPigVThttp://www.blogger.com/profile/13822643534037160541noreply@blogger.comtag:blogger.com,1999:blog-8256260706621645238.post-7441317193892420352016-03-31T17:28:00.000-04:002016-03-31T17:28:41.501-04:00Seven year navel gazing...The first post of this blog documented that I was preparing to start a new job. That was December of 2008. Seven years seems like a long ago.<br />
<br />
On Monday I start another new job.<br />
<br />
So I feel like this is a good opportunity to reflect on what these past seven years has meant to me and my career. A chance to thank the universe for what I've experienced, to thank the folks I've met, and to recognize where I think I'm going.<br />
<br />
The month after that initial post I started working at <a href="http://mywebgrocer.com/" target="_blank">MyWebGrocer</a>. I had been hired to work on the eCommerce product and introduce some improvements to the development processes. I had played a similar role at my prior employer by implementing an automated build system and a few other bits of tooling. At MyWebGrocer, however, I was able to expand on that prior work. I led the introduction of a continuous integration server, static code analysis, automated unit testing, some scrum practices, and more. The team I was on kicked ass; our product was pretty stable, we were delivering new functionality, refactoring to reduce complexity and lines of code, and enjoying each others' company. After a few years I took a management position. While I eventually resumed my technical career - for those two years I had the privilege of managing the best team with whom I've had the pleasure of working. When I decided to leave management the MWG executive team was supportive; allowing me to resume my technical career without leaving the company. Not every employer would have done that; I'm appreciative.<br />
<br />
My tenure at MWG coincides with my increased participation in the development community around Burlington, VT. I increased my involved with the <a href="http://www.meetup.com/VTCode/" target="_blank">VT .NET user group</a> which led to co-founding the <a href="http://vtcodecamp.org/" target="_blank">VT Code Camp</a>. When MyWebGrocer founded the <a href="http://hackvt.com/" target="_blank">HackVT</a> event they invited me to be on the planning team. I've continued to serve on the organizing team for HackVT. I've met amazing members of our technical community, too. Organizers of other local user groups, students, presenters, sponsors, employers, journalists, writers, etc. My participation in this community will continue regardless of where I work, and I'm confident that MWG's support of the local development community will continue, too. They've been reliable sponsors for VT Code Camp, HackVT, and other local development events.<br />
<br />
As I transition into my next role MWG is six times larger than on my first day. I look at how the development team works and I see my fingerprints on a lot of it. It's not been a perfect experience. I've made mistakes and there are elements of what I would have like to have contributed to the MWG experience which are unfulfilled. This is the real world, after all. But these past seven years have (so far) been the highlight of my professional career.<br />
<br />
Come Monday, when I start at <a href="http://www.renewablenrgsystems.com/" target="_blank">Renewable NRG Systems</a> I will be a significantly better, and more well rounded, developer than I was seven years ago. I'm eager to dive into a different industry for an organization which has a different corporate culture. New people, new knowledge - it's going to be great!<br />
<br />
So thank you to the MWG team for helping me grow professionally. And for your friendships. Thank you to RNRG for the opportunity to challenge myself in an industry I feel is important.<br />
<br />
Thanks universe.BigPigVThttp://www.blogger.com/profile/13822643534037160541noreply@blogger.comtag:blogger.com,1999:blog-8256260706621645238.post-11404762709453179472015-12-09T19:54:00.002-05:002015-12-09T19:54:39.349-05:00What HTTP Status Code to returnA colleague shared a link to <a href="http://racksburg.com/choosing-an-http-status-code/">http://racksburg.com/choosing-an-http-status-code/</a> with me today. It contains a nice rundown of when to have your API return certain status code values.BigPigVThttp://www.blogger.com/profile/13822643534037160541noreply@blogger.comtag:blogger.com,1999:blog-8256260706621645238.post-11592307231687756132015-11-10T09:11:00.002-05:002015-11-10T09:11:50.638-05:00Interesting link to keepNot really a blog post here. Just don't want to lose the URL for a calendar that has a round up of Vermont based events of interest to entrepreneurs and development folks: <a href="http://www.vermontventurenetwork.org/?view=calendar&month=November-2015">http://www.vermontventurenetwork.org/?view=calendar&month=November-2015</a>BigPigVThttp://www.blogger.com/profile/13822643534037160541noreply@blogger.comtag:blogger.com,1999:blog-8256260706621645238.post-72733199728524989612015-07-08T06:00:00.000-04:002015-07-08T14:59:25.947-04:00End to End testing takedownGoogle's Testing Blog has a post, <a href="http://googletesting.blogspot.com/2015/04/just-say-no-to-more-end-to-end-tests.html" target="_blank">Just Say No to More End-to-End Tests</a>, which does a nice job of articulating my experience with automated testing. Specifically I've found unit testing to be more beneficial than integration testing and integration testing more beneficial than end to end testing (E2E).<br />
<br />
The immediate feedback provided by unit tests, which run significantly faster than the other two, helps me as a developer. Using a TDD approach, and frequently invoking my unit tests, the design is refined and failing code is identified quickly. At my current employer we've tied the unit tests into the continuous integration process so that if code coverage drops by 1% or more the build fails. That's a nice defense against having the code atrophy. I also like the closing statement from Martin Fowler's post, <a href="http://martinfowler.com/bliki/TestPyramid.html" target="_blank">Test Pyramid</a>: <br />
<blockquote class="tr_bq">
<i>In particular I always argue that high-level tests are there as a second line of test defense. If you get a failure in a high level test, not just do you have a bug in your functional code, you also have a missing unit test. Thus whenever you fix a failing end-to-end test, you should be adding unit tests too.</i></blockquote>
<br />
Integration and E2E tests have value, and I'm not arguing they be skipped, but I've found the greatest ROI comes with unit tests. BigPigVThttp://www.blogger.com/profile/13822643534037160541noreply@blogger.comtag:blogger.com,1999:blog-8256260706621645238.post-50751097364578909592015-05-18T15:44:00.001-04:002015-05-18T15:44:12.092-04:00Bookmarking future readingA co-worker was passing around a link to a Mozilla document that provides <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/A_re-introduction_to_JavaScript" target="_blank">A re-introduction to JavaScript</a> and I don't want to lose the link. It looks to be a thorough article - which requires more time than I can currently dedicate to it, hence the bookmark post.<br />
<br />
Nothing to read here, citizen. Move along.BigPigVThttp://www.blogger.com/profile/13822643534037160541noreply@blogger.comtag:blogger.com,1999:blog-8256260706621645238.post-21490592575984052632015-04-03T15:21:00.001-04:002015-04-03T16:57:10.529-04:00Adventures (and frustrations) in NuGet package creationI'm frustrated.<br />
<br />
And disappointed.<br />
<br />
Frustrated and disappointed. But more knowledgeable.<br />
<br />
I spent a good part of today trying to get our CI build to create our NuGet packages so the resulting packages list their dependencies without developers having to manually edit the .nuspec file unless they have to. Unfortunately, I've failed, but I know a little more about how to interact with our <a href="https://www.jetbrains.com/teamcity/" target="_blank">TeamCity</a> installation and the <span style="font-family: "Courier New",Courier,monospace;">nuget pack</span> command.<br />
<br />
What I learned was that our build process invokes the <span style="font-family: "Courier New",Courier,monospace;">nuget pack</span> command which creates the package. Reviewing <a href="http://docs.nuget.org/consume/Command-Line-Reference#pack-command" target="_blank">the documentation for that command</a> I read about the <a href="http://docs.nuget.org/consume/Command-Line-Reference#pack-command-options" target="_blank">IncludeReferencedProjects option</a> which is described as doing the following:<br />
<blockquote class="tr_bq">
<span style="font-family: "Trebuchet MS",sans-serif;">Include referenced projects either as dependencies or as part of the package. If a referenced project has a corresponding nuspec file that has the same name as the project, then that referenced project is added as a dependency. Otherwise, the referenced project is added as part of the package.</span></blockquote>
"This is great!" I thought, "The solution I'm currently working on has project references that met that description. I won't have to explicitly declare the dependency."<br />
<h2>
What I was trying to do</h2>
Maybe a brief note about the solution is in order. It's for a WebAPI
and has several projects in it, not all of which are published as NuGet
packages. The projects are:<br />
<ul>
<li><span style="font-family: "Courier New",Courier,monospace;">MyApp </span></li>
<li><span style="font-family: "Courier New",Courier,monospace;">MyApp.Application</span></li>
<li><span style="font-family: "Courier New",Courier,monospace;">MyApp.Api</span></li>
<li><span style="font-family: "Courier New",Courier,monospace;">MyApp.Api.WebHost</span></li>
<li><span style="font-family: "Courier New",Courier,monospace;">MyApp.Repository</span></li>
</ul>
With the exception of <span style="font-family: "Courier New",Courier,monospace;">MyApp.Api</span> they each result in a NuGet package. Mainly because even though we're moving to have all calls go through the <span style="font-family: "Courier New",Courier,monospace;">MyApp.Api.WebHost</span>
which is the package that's automatically deployed to the web servers,
there are some older projects that continue to need access to <span style="font-family: "Courier New",Courier,monospace;">MyApp</span>, <span style="font-family: "Courier New",Courier,monospace;">MyApp.Application</span> and <span style="font-family: "Courier New",Courier,monospace;">MyApp.Repository</span>.<br />
<br />
As you would guess, there are project references between some of the projects. For example, <span style="font-family: "Courier New",Courier,monospace;">MyApp.Api.WebHost</span> references <span style="font-family: "Courier New",Courier,monospace;">MyApp</span>, <span style="font-family: "Courier New",Courier,monospace;">MyApp.Application</span> and <span style="font-family: "Courier New",Courier,monospace;">MyApp.Repository</span>. What we've been doing is modifying the web host project's <a href="http://docs.nuget.org/create/nuspec-reference#specifying-dependencies" target="_blank">.nuspec file to declare the dependencies</a> on <span style="font-family: "Courier New",Courier,monospace;">MyApp</span>, <span style="font-family: "Courier New",Courier,monospace;">MyApp.Application</span> and <span style="font-family: "Courier New",Courier,monospace;">MyApp.Repository</span>. <br />
<h2>
What I tried</h2>
Given this configuration I thought the <span style="font-family: "Courier New",Courier,monospace;">IncludeReferencedProjects</span> option would allow us to only declare package dependencies that existed outside the solution.<br />
<br />
So I sat with a co-worker who is very knowledgeable about the TeamCity templates we have. He showed me the how to include that option on the build step which creates the NuGet package. We copied the template to a temporary one to test with, added the option, associated the MyApp build to that template, modified the .nuspec file to remove the explicit package dependency declarations, committed the code, and sat back to see the results.<br />
<br />
It didn't work.<br />
<br />
The resulting nupkg file doesn't list the dependencies. We then modified the way nuget was run to turn up the verbosity (<span style="font-family: "Courier New",Courier,monospace;">-Verbosity detailed</span>) and ran it again to see if we learned anything useful. All we saw in our build log was <span style="font-family: "Courier New",Courier,monospace;">[pack] Dependencies: None</span>. Then my co-worker noticed in the <a href="http://docs.nuget.org/consume/Command-Line-Reference#pack-command-examples" target="_blank">pack command examples</a> that in addition to running <span style="font-family: "Courier New",Courier,monospace;">nuget pack</span> against the .nuspec file you can also run it against the .csproj file. So we tried that. That change resulted in a number of failing builds because the .csproj files had references to Visual Studio 10 and we're using VS2013 - doesn't make a difference to MSBuild because it knows what version it is, and it didn't matter to nuget pack when we targeted the .nuspec file (presumably because it didn't need it) but when we target the .csproj file it broke. So we changed the project files so:<br />
<span style="font-size: x-small;"><span style="font-family: "Courier New",Courier,monospace;"><visualstudioversion condition="'$(VisualStudioVersion)' == ''"><span style="background-color: white;"><VisualStudioVersion Condition="'$(VisualStudioVersion)' == ''"><span style="background-color: yellow;">10</span>.0</VisualStudioVersion></span></visualstudioversion></span></span><br />
became<br />
<span style="font-size: x-small;"><span style="font-family: "Courier New",Courier,monospace;"><span style="background-color: white;"><VisualStudioVersion Condition="'$(VisualStudioVersion)' == ''"><span style="background-color: yellow;">12</span>.0</VisualStudioVersion></span></span></span><br />
<br />
and <br />
<span style="font-size: x-small;"><span style="font-family: "Courier New",Courier,monospace;"><import 0="" 255="" background-color:="" project="$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v<span style=" rgb=""><Import Project="$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v<span style="background-color: yellow;">10</span>.0\WebApplications\Microsoft.WebApplication.targets" Condition="false" /></import></span></span><br />
became<br />
<span style="font-size: x-small;"><span style="font-family: "Courier New",Courier,monospace;"><import 0="" 255="" background-color:="" project="$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v<span style=" rgb=""><Import Project="$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v<span style="background-color: yellow;">12</span>.0\WebApplications\Microsoft.WebApplication.targets" Condition="false" /></import></span></span><br />
<br />
Neither of these changes fixed the problem. We were continuing to see an error that read:<br />
<span style="font-size: x-small;"><span style="font-family: "Courier New",Courier,monospace;">[pack] Microsoft.Build.Exceptions.InvalidProjectFileException: The imported project "C:\Program Files (x86)\MSBuild\Microsoft\VisualStudio\<span style="background-color: yellow;">v10.0</span>\WebApplications\Microsoft.WebApplication.targets" was not found. Confirm that the path in the <import> declaration is correct, and that the file exists on disk. [the path to my .csproj file]<br />[pack] at Microsoft.Build.Shared.ProjectErrorUtilities.ThrowInvalidProject(String errorSubCategoryResourceName, IElementLocation elementLocation, String resourceName, Object[] args)<br />[pack] at Microsoft.Build.Shared.ProjectErrorUtilities.ThrowInvalidProject(IElementLocation elementLocation, String resourceName, Object arg0)<br />[pack] at Microsoft.Build.Evaluation.Evaluator`4.ExpandAndLoadImports(String directoryOfImportingFile, String importExpressionEscaped, ProjectImportElement importElement)<br />[pack] at Microsoft.Build.Evaluation.Evaluator`4.EvaluateImportElement(String directoryOfImportingFile, ProjectImportElement importElement)<br />[pack] at Microsoft.Build.Evaluation.Evaluator`4.PerformDepthFirstPass(ProjectRootElement currentProjectOrImport)<br />[pack] at Microsoft.Build.Evaluation.Evaluator`4.Evaluate()<br />[pack] at Microsoft.Build.Evaluation.Evaluator`4.Evaluate(IEvaluatorData`4 data, ProjectRootElement root, ProjectLoadSettings loadSettings, Int32 maxNodeCount, PropertyDictionary`1 environmentProperties, ILoggingService loggingService, IItemFactory`2 itemFactory, IToolsetProvider toolsetProvider, ProjectRootElementCache projectRootElementCache, BuildEventContext buildEventContext, ProjectInstance projectInstanceIfAnyForDebuggerOnly)<br />[pack] at Microsoft.Build.Evaluation.Project.ReevaluateIfNecessary(ILoggingService loggingServiceForEvaluation)<br />[pack] at Microsoft.Build.Evaluation.Project.Initialize(IDictionary`2 globalProperties, String toolsVersion, String subToolsetVersion, ProjectLoadSettings loadSettings)<br />[pack] at Microsoft.Build.Evaluation.Project..ctor(String projectFile, IDictionary`2 globalProperties, String toolsVersion, String subToolsetVersion, ProjectCollection projectCollection, ProjectLoadSettings loadSettings)<br />[pack] at NuGet.Commands.PackCommand.BuildFromProjectFile(String path)<br />[pack] at NuGet.Commands.PackCommand.BuildPackage(String path)<br />[pack] at NuGet.Commands.PackCommand.ExecuteCommand()<br />[pack] at NuGet.Commands.Command.Execute()<br />[pack] at NuGet.Program.Main(String[] args)<br />[pack] Process exited with code 1</import></span></span><br />
<br />
For some reason neither of us understood, the project file was still looking for version 10, even though the file on the build server had version 12 specified. We decided to change the way <span style="font-family: "Courier New",Courier,monospace;">nuget pack</span> was being called to include the property assignment of the <span style="font-family: "Courier New",Courier,monospace;">VisualStudioVersion</span> (<span style="font-size: x-small;"><span style="font-family: "Courier New",Courier,monospace;">-Properties Configuration=Release;VisualStudioVersion=12.0</span></span>).<br />
<br />
This got us a successful build and the resulting nupkg file started listing our dependencies as expected.<br />
<br />
So the <span style="font-family: "Courier New",Courier,monospace;">IncludeReferencedProjects</span> option only appears to work when <span style="font-family: "Courier New",Courier,monospace;">nuget pack</span> targets the project file.<br />
<h2>
Short lived victory lap</h2>
After high fives all around we set about changing the <i>real</i> template for our CI builds. Once that was done we kicked off builds for the projects which used that template. What we found was that even with the changes we made related to the <span style="font-family: "Courier New",Courier,monospace;">VisualStudioVersion</span>, in both the properties passed from the <span style="font-family: "Courier New",Courier,monospace;">nuget pack</span> command <i>and</i> the project files, some of the builds kept failing because the version being sought was v10 not v12.<br />
<h2>
Observations before reverting</h2>
What we noticed was the problem seemed to occur when project A.1 was being packed but project A.1 referenced A.2 and the <span style="font-family: "Courier New",Courier,monospace;">import</span> line that was causing the exception was in project A.2. For example, during the pack of project MyApp.Account.Api.WebHost the exception line was <br />
<span style="font-size: x-small;"><span style="font-family: "Courier New",Courier,monospace;">[pack] Microsoft.Build.Exceptions.InvalidProjectFileException: The imported project "C:\Program Files (x86)\MSBuild\Microsoft\VisualStudio\<span style="background-color: yellow;">v10.0</span>\WebApplications\Microsoft.WebApplication.targets" was not found. Confirm that the path in the <import> declaration is correct, and that the file exists on disk. F:\Agent\Work\3b114de58491d1e6\src\MyApp.Account.Api\<span style="background-color: yellow;">MyApp.Account.Api.csproj</span></import></span></span><br />
<br />
At this point we got stumped because all the project files had the hard coded v12.0 value. Somehow the <span style="font-family: "Courier New",Courier,monospace;">import</span> is being given the wrong path. We can't find the cause of it and after a half day we had to move on.<br />
<h2>
Appeal for advice</h2>
If anyone knows how we might successfully revisit this and work past the problems; either by telling us why the <span style="font-family: "Courier New",Courier,monospace;">IncludeReferencedProjects</span> option wasn't working from the .nuspec file or explaining what we have to do related to the <span style="font-family: "Courier New",Courier,monospace;">VisualStudioVersion</span>, (or something else we're not seeing that you know of) it would be appreciated. Tweet me.BigPigVThttp://www.blogger.com/profile/13822643534037160541noreply@blogger.comtag:blogger.com,1999:blog-8256260706621645238.post-81487158717708640502015-03-24T09:58:00.001-04:002015-03-24T09:58:34.709-04:00"Coding like a Girl" - great read!Last night I had the pleasure of attending the second anniversary party for the <a href="http://www.meetup.com/Girl-Develop-It-Burlington/" target="_blank">Girl Develop It! Burlington, VT chapter</a>. It was a chance to see some friends I've made through the local developer community, meet some people in our industry who were new to me, and reconnect with a few of the people who I met the handful of times I was a TA for a GDI event. At one point a conversation I was involved in turned to the challenges of being a technical professional who chooses to dress in a more feminine manner. It was amazing to listen to these accomplished professionals discuss how their choice of outfit would, in many cases, predict how they would be received. At that point <a href="https://twitter.com/KathleenDollard" target="_blank">Kathleen Dollard</a> recommended a blog post entitled <a href="https://medium.com/@sailorhg/coding-like-a-girl-595b90791cce" target="_blank">"Coding Like a Girl"</a>.<br />
<br />
I read it this morning and believe it is worth sharing. The anecdote shared in the post about the experience <a href="https://twitter.com/triketora" target="_blank">Tracy Chou</a>, an engineer at Pinterest, had at a technical conference was facinating:<br />
<blockquote class="tr_bq">
A couple years ago she attended a technical conference and on the first day, she wore a dress. When she walked around the conference, no one came up to talk to her. When she asked people very technical questions about their stack, questions she assumed would indicate that she was a programmer, she was brushed aside and told, “You wouldn’t understand.” She went back home that night really frustrated and flustered. She almost didn’t feel like going to the conference the next day. But she did and wore a nerdy tshirt and jeans instead, and she had a better experience that day. People assumed she was technical and didn’t dilute their explanations to her.</blockquote>
That an industry peer had to change her appearance in order to be taken seriously is disappointing to me as a guy - as a woman it must be infuriating.<br />
<br />
I like to think I do a decent job when dealing with folks, I'm reasonably self aware. Yet I know there have been a few times where I've judged other guys who come to a tech event dressed in a suit and assume they're sales people and not "real" technical folks. If I've done that to another guy - with whom I have more in common - what biases do I have around a woman's appearance? Have they colored my interactions with anyone?<br />
<br />
We can only do our best, I suppose. I'm going to try and be more aware of my own biases when it comes to appearance and adopt the advice offered in the post, "Assume people are as or more qualified than you" regardless of their appearance. I hope that you take a few minutes to read the blog post, too.BigPigVThttp://www.blogger.com/profile/13822643534037160541noreply@blogger.comtag:blogger.com,1999:blog-8256260706621645238.post-69659075647940389692015-03-14T21:33:00.000-04:002015-03-14T21:33:08.707-04:00A very important read for software professionalsAlan Stevens has<a href="http://alanstevens.us/post/113615371526/values-driven-development" target="_blank"> a blog post</a> that I think is a very important read for anyone who is a software professional. I think that this is an especially useful read for developers just entering the field. Do yourself a favor and take the time to read this.BigPigVThttp://www.blogger.com/profile/13822643534037160541noreply@blogger.comtag:blogger.com,1999:blog-8256260706621645238.post-85876412140502781612015-02-06T10:36:00.001-05:002015-02-06T10:36:15.743-05:00Creating Visual Studio TemplatesI spent most of yesterday creating a solution template for Visual Studio 2013 so our developers can begin a project with about an hour's worth of plumbing already done for them. It was an interesting task and one that gave me a lot of satisfaction having completed. I like knowing that I've reduced developers' time for a 1 hour task to 5 minutes (more on why it's not less than that shortly).<br />
<br />
First, there were a few links that proved invaluable:<br />
<ul>
<li><a href="https://msdn.microsoft.com/en-us/library/ms247121.aspx" target="_blank">Creating Visual Studio templates</a></li>
<li><a href="https://msdn.microsoft.com/en-us/library/ms185308.aspx" target="_blank">How to create multi-project templates</a></li>
<li><a href="https://msdn.microsoft.com/en-us/library/ms185311.aspx" target="_blank">How to substitute parameters in a template</a></li>
<li><a href="https://msdn.microsoft.com/en-us/library/eehb4faa.aspx" target="_blank">Template parameters</a> </li>
<li><a href="https://msdn.microsoft.com/en-us/library/xwkxbww4.aspx" target="_blank">Visual Studio template schema reference</a></li>
</ul>
The process I followed consisted of creating a solution that I was going to use as a reference point. It had all the projects, folders, classes, dependencies, etc. set up. Then I exported each project as a template and went through each one making sure my parameter substitutions were in place. I then tested each individual project template to ensure they behaved as expected. Finally, I hand-rolled a multi-project template that tied them together. That part was simple enough.<br />
<br />
Where I started to hit a snag was that the multi-project template behavior creates a sub-folder for the first project and within that a sub-folder for each project (rather than having the project folders all created as peers of the *.sln file). There doesn't appear to be a way to change that behavior, which is unfortunate, because it prevents NuGet dependencies from working properly. So while the template creates everything in a matter of seconds, the developer then has to close Visual Studio, relocate five folders to the correct location and edit the *.sln file. That's why the template only saves 91.5% of a developers time rather than 99.8%.<br />
<br />
Still pretty good, though.BigPigVThttp://www.blogger.com/profile/13822643534037160541noreply@blogger.comtag:blogger.com,1999:blog-8256260706621645238.post-75988127708781707162015-01-14T08:31:00.000-05:002015-01-14T08:31:22.603-05:00Getting to a command prompt from Windows ExplorerMany years ago there was a utility I had installed on my Windows95 or Windows NT box that added an item to the context menu of Windows Explorer allowing me to open a command window with the folder I had in focus as the working directory. Somewhere along the line between Windows Vista and Windows 7 (my current OS) that utility stopped working. I never followed up to find it again and got along without it - though I would miss it from time to time.<br />
<br />
Last week a co-worker made me aware that functionality is available in Windows 7, but it's slightly hidden. I have no idea how long it's been an option but am very happy to know about it - and I like to share what makes me happy.<br />
<br />
Normally, if you right-click on a folder in Windows Explorer you get the context menu. Here's a shot of what mine looks like:<br />
<div class="separator" style="clear: both; text-align: center;">
</div>
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg56WQlUZjDU45x48aTBRtMaBKJdCGwcHKmWr4t8pZsKC_jlmp7-GU6VY3nb5pDYGfwIj4OIutN7TVxdN-Qby3MD60siZmYdib4AOWV8hf0LpAqeCA934Yt5ny0yKbS7nzNzSN1fn1ju6M/s1600/Basic.jpg" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img alt="Context menu" border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg56WQlUZjDU45x48aTBRtMaBKJdCGwcHKmWr4t8pZsKC_jlmp7-GU6VY3nb5pDYGfwIj4OIutN7TVxdN-Qby3MD60siZmYdib4AOWV8hf0LpAqeCA934Yt5ny0yKbS7nzNzSN1fn1ju6M/s1600/Basic.jpg" height="534" title="" width="640" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">Context Menu</td></tr>
</tbody></table>
<br />
Yours probably looks similar. But what my co-worker pointed out was that if you hold down the shift key when you do the right-click the menu includes an extra item:<br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjLCaFJyBFMEQ_aJFM7Or-Klmdh_o3fHSEQn_Na5IXJgrAgL1HNfIkgvkLbu46FU8JR0LFZO5dmQul3o06Idhn-VSD8Qimh9-3_ZAZFhGCIyc9lHv-MvDrtIhFuOyzzOJ-Ht1jng4sFago/s1600/Shifted.jpg" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img alt="context menu after shift key is held down" border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjLCaFJyBFMEQ_aJFM7Or-Klmdh_o3fHSEQn_Na5IXJgrAgL1HNfIkgvkLbu46FU8JR0LFZO5dmQul3o06Idhn-VSD8Qimh9-3_ZAZFhGCIyc9lHv-MvDrtIhFuOyzzOJ-Ht1jng4sFago/s1600/Shifted.jpg" height="512" title="" width="640" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">Context Menu, now with shift key</td></tr>
</tbody></table>
<br />
I have no idea why this isn't just part of the regular context menu, but I'm happy to know it's there now.<br />
<div class="separator" style="clear: both; text-align: center;">
</div>
<br />BigPigVThttp://www.blogger.com/profile/13822643534037160541noreply@blogger.comtag:blogger.com,1999:blog-8256260706621645238.post-1296119002425764802014-12-10T16:24:00.001-05:002014-12-10T16:24:10.722-05:00On the heels of our recent WTF.JS sessionOur most recent meeting at the VT .NET user group was a series of lightening talks covering different JavaScript frameworks. Today I was directed to <a href="http://todomvc.com/" target="_blank">TodoMvc</a> which is a site where the same application has been implemented multiple times using different MV* JavaScript frameworks. It allows developers who are considering the various (and numerous) options to "kick the tires" and see which approach might work best for them.<br />
<br />
Neat!BigPigVThttp://www.blogger.com/profile/13822643534037160541noreply@blogger.comtag:blogger.com,1999:blog-8256260706621645238.post-78969812993945382202014-11-17T10:34:00.002-05:002014-11-17T10:34:32.503-05:00Nice writeup on bulk renaming of files in WindowsRecently I had to rename a bunch of files in a Windows folder to have the same prefix. I found <a href="http://www.windows-commandline.com/rename-file-extensions-bulk/" target="_blank">a page</a> on the <a href="http://www.windows-commandline.com/" target="_blank">Windows Command Line blog</a> that provided a nice write up on a number of techniques around bulk renaming.BigPigVThttp://www.blogger.com/profile/13822643534037160541noreply@blogger.comtag:blogger.com,1999:blog-8256260706621645238.post-45690037650970425032014-07-16T21:52:00.000-04:002014-07-16T21:52:25.732-04:00Running Our Internal HackathonFor over a year now one of the best responsibilities I've had at work is to organize internal hackathons for our development team. Recently I told some peers how gratifying it has been to run these events. Some of them asked for more information as they consider introducing a similar event at their own shop.<br />
<br />
<b><span style="font-size: large;">
Format</span></b><br />
Ours is a two day event where staff are encouraged to be creative, explore new technologies, work with different folks than they would normally, and <i>have fun</i>. We try to have it be a 100% participation event, but that can be tough with vacations and the like. We encourage team members who are concerned about a deadline or other conflicting priority to talk to their manager. We really want to make space for everyone to participate and the managers will attempt to move mountains to encourage participation. Our event is an exhibition format, not a competition. The opportunity to stretch, explore and showcase their talents has (so far) been enough of a reward that we've not felt the need to have prizes, judging, etc.<br />
<br />
First thing on Day 1 there is an event kick-off meeting. The point of the kick-off is to build excitement and hit a few points about logistics like food, how we will respond to any production issue that may come up during the event, etc. We also take that opportunity to remind folks about some of the ground rules, and any last minute announcements. It's worth mentioning that teams can start as early as they like on Day 1, including midnight if they choose, but the kick-off is the official start.<br />
<br />
After the kick-off the teams disperse to work on their projects and don't have to come together again until the afternoon of Day 2 for the presentations. We only expect people to work business hours but they are welcome
to stay late or even stay over if that suits them. We set up a couple of cots
in our game room for anyone who decides to stay, or just needs a nap.
We bring in food for the participants, too. Lunch and snacks on Day 1. Breakfast, lunch and snacks on Day 2.<br />
<br />
We start the presentations around 2:30 on Day 2. Because the event is an exhibition we ask the teams to touch on three questions during their presentations:<br />
<ul>
<li>What were you trying to do?</li>
<li>How did you approach the problem?</li>
<li>What did you learn?</li>
</ul>
We've tried two formats for the presentations; "lightning talks" and "science fair." The first three events we did as "lightning talks" with each team coming up to the projector and PA to showcase their project. This had the benefit of everyone getting the chance to see each project. Additionally, we have some remote staff who wanted to see the presentations so we used GoToMeeting to enable that (which had the added benefit of making it something I could easily record). The down side to this format is it feels <i>long</i>. Additionally, each team could only get 5 minutes to present. We had to fit all the presentations within a two hour window. Many teams found that to be a challenge. <br />
<br />
With our most recent event we switched to a "science fair" format where everyone would go visit each team's space and hear the presentation. The advantage to this approach turned out to be the presentations were much more interactive and folks could spend as much, or as little, time as they wanted with each project. There were a few down sides. A team's members would have to take shifts to visit other projects; someone had to stay behind to demo the team project. This lead to not everyone seeing every project. Remote staff couldn't participate in real time and will have to rely on videos of each team presentation I made using my phone.<br />
<br />
The other thing the new format lacked was a clear end of the event. I think we all missed that and will introduce a way to punctuate the event next time. Based on the initial feedback, though, the "science fair" format was clearly preferred by everyone involved.<br />
<br />
<b><span style="font-size: large;">
Project Ideas</span></b><br />
Even though the event is not a competition we do have some ground rules about the projects. People pitching a project idea need to have a reasonable answer for at least one of the following:<br />
<ul>
<li>How does this benefit the company?</li>
<li>How does this benefit your Team?</li>
<li>How does this benefit your dev life/career in our shop?</li>
</ul>
The interpretation of "reasonable answer" is pretty flexible, but the staff has really respected the spirit of these guidelines.<br />
<br />
Once someone has a project they would like to propose they enter it in a shared spreadsheet. We ask people who are adding a project proposal to list themselves as the "Team Leader/Idea Person." That way other people can talk to them about joining the team. Plus, if they have a good idea but don't want to be the "leader" they can work out roles with folks who want to join the team. Teams can be as small as or as big as their idea requires. We discourage people from working solo because part of this is to encourage people to build relationships across the departments who are participating.<br />
<h2>
</h2>
<b><span style="font-size: large;">
Logistics</span></b><br />
The project sign up spreadsheet serves a few other uses. I use it to identify which teams are large enough to assign a conference room. We book all the conference rooms on our floor for the duration of the event so teams have a dedicated space to work on their project. Bigger teams get the bigger conference rooms. The spreadsheet also allows me to reach out to staff who haven't picked a project so I can facilitate a match or identify folks who are opting out of the event for whatever reason.<br />
<br />
Before our most recent event I also set up a survey in Google Drive so people could be included in the head count for the food order. Our wonderful admin, Meg, needs to order the meals at least a week before the event. Locking in how many people are eating each meal prevents us from ordering too much (we had a fair amount go to waste the prior event when few people stayed for dinner). The survey also allowed us to solicit information about food allergies or other dietary restrictions that would inform the food order.<br />
<br />
Communications during the event, though, are intentionally low tech. Any announcements or group communications are done by sneaker-net. I go room to room to let each team know when food is available, when the presentation deadline is approaching and anything else that needs sharing. One of the points I make in the event kick-off is that participants should refrain from checking email so they don't get pulled into the normal, daily activity of the business. Management, from the CEO down, has made the investment in these two days by green-lighting the event - we don't want to squander that opportunity.<br />
<br />
Finally, another survey is sent out a few days after the event to ask what went well, what could have gone better and what, if anything, should change. This is important to inform how we plan the next event. For example, the change to the presentation format came from a post-event survey.<br />
<br />
<b><span style="font-size: large;">So...</span></b><br />
After running four of these events I believe we've more or less got the process of organizing the event worked out. The participants, too, seem to be getting the rhythm and sizing their projects to something that can be accomplished in the time frame of the event. The first few events had teams that were over ambitious and had incomplete projects - which we were OK with as long as they had a good answer to "What did you learn?" :-)<br />
<br />
If you're considering organizing an internal hackathon they can be a wonderful opportunity for your team to do a deep dive on some technology, build relationships, and maybe even incubate a new business opportunity.<br />
BigPigVThttp://www.blogger.com/profile/13822643534037160541noreply@blogger.comtag:blogger.com,1999:blog-8256260706621645238.post-13833512078686343472014-05-12T12:00:00.000-04:002014-05-12T13:03:31.802-04:00Free Programming BooksEarly in my career I benefited greatly from reading a few books on programming. There were two books in particular that I believe raised the level of what I was doing professionally. First was Steven Feuerstein's <a href="http://shop.oreilly.com/product/9780596514464.do">Oracle PL/SQL Programming</a> (I think I had the second edition). The other came years later and was <a href="http://shop.oreilly.com/product/9780596007126.do">Head First Design Patterns</a> by Freeman, Robson, Bates and Sierra.<br />
<br />
So I know the benefit of reading programming books - especially when looking for a deep dive on a technology. Which is why I was happy a colleague sent me this link to an index of free programming books on GitHub. It covers a variety of languages and did I mention is free? The link is <a href="https://github.com/vhf/free-programming-books/blob/master/free-programming-books.md">https://github.com/vhf/free-programming-books/blob/master/free-programming-books.md</a><br />
<br />
No idea if the next book to help me level up as a professional is there, but I'm going to hope so.BigPigVThttp://www.blogger.com/profile/13822643534037160541noreply@blogger.comtag:blogger.com,1999:blog-8256260706621645238.post-78696171021224082832014-04-22T10:27:00.003-04:002014-04-22T10:30:04.882-04:00Code and slide deck from my April 2014 presentation to VT .NET user groupLast night I presented at the VT .NET on the topic of delegates. The slide deck and code from my presentation are now available.<br />
<ul><li><b>Slides:</b> <a href="http://www.slideshare.net/robhalevt/delegation-and-delegates">http://www.slideshare.net/robhalevt/delegation-and-delegates</a></li>
<li><b>Code:</b> <a href="https://github.com/robhalevt/20140421_VTdotNET_DelegationAndDelegates" target="_blank">https://github.com/robhalevt/20140421_VTdotNET_DelegationAndDelegates </a></li>
</ul><br />
<iframe src="http://www.slideshare.net/slideshow/embed_code/33802792" width="427" height="356" frameborder="0" marginwidth="0" marginheight="0" scrolling="no" style="border:1px solid #CCC; border-width:1px 1px 0; margin-bottom:5px; max-width: 100%;" allowfullscreen> </iframe> <div style="margin-bottom:5px"><strong> <a href="https://www.slideshare.net/robhalevt/delegation-and-delegates" title="VT.NET user group 2014-04-21: Delegation and C# delegates" target="_blank">VT.NET user group 2014-04-21: Delegation and C# delegates</a> </strong> from <strong><a href="http://www.slideshare.net/robhalevt" target="_blank">Rob Hale</a></strong> </div>BigPigVThttp://www.blogger.com/profile/13822643534037160541noreply@blogger.comtag:blogger.com,1999:blog-8256260706621645238.post-77533607791328863532014-03-17T15:23:00.000-04:002014-03-17T15:23:37.785-04:00Javascript Patterns CollectionA co-worker shared this link to a collection of Javascript patterns that is marvelous. Had to share: <a href="http://shichuan.github.io/javascript-patterns/">http://shichuan.github.io/javascript-patterns/</a>BigPigVThttp://www.blogger.com/profile/13822643534037160541noreply@blogger.comtag:blogger.com,1999:blog-8256260706621645238.post-50582734642839458922013-09-18T18:14:00.002-04:002013-09-18T18:14:51.318-04:00A realization in advance of VT Code Camp 5This coming Saturday is our fifth <a href="http://vtcodecamp.org/" target="_blank">Vermont Code Camp</a>!<br />
<br />
Those of us involved in the planning are running around engaged in our last minute preparations to ensure this event will be as successful (or more) than our prior 4 camps. One of the things we do differently from other code camps is engage the whole tech community in our area. Most code camps are centered on .NET and other Microsoft platforms - while there are BAR Camps and other events for different technology stacks. But Vermont having such a small population we've found that working with as many of the user groups as we can gets a much more robust set of speakers, exposure to different technologies and a wider sense of community.<br />
<br />
So we usually provide a hand out listing the various technology user groups in the area. Today as I was compiling the list I was struck by how vibrant the Vermont technology scene really is. <a href="https://docs.google.com/document/d/1fPZB56zBZ_P3uF8RQsVj3U-UjWb1G4SWTzWYOUuLLTg/edit?usp=sharing" target="_blank">Here's the list</a> (sorry for the spoiler VTCC5 campers). It's a page and a half of groups and events that demonstrate Vermont has it going on!<br />
<br />
I'm moving onto the next task to prepare for this weekend - but I'm very happy to be part of such a wonderful community.<br />
<br />
Oh, by the way, have you <a href="http://ow.ly/oUfQi" rel="nofollow" target="_blank">registered for VT Code Camp</a> yet?BigPigVThttp://www.blogger.com/profile/13822643534037160541noreply@blogger.comtag:blogger.com,1999:blog-8256260706621645238.post-7668186421305727152013-07-17T13:52:00.000-04:002013-07-18T10:04:39.053-04:00Slides from my July 15 presentation to the VT .NET user groupMonday I presented a talk to the VT .NET user group titled "<a href="http://www.meetup.com/VTCode/events/118901402/" target="_blank">Using the Decorator Design Pattern to Address Cross-Cutting Concerns</a>". The slides for this presentation are now available on SlideShare at <a href="http://ow.ly/n3MxL">http://ow.ly/n3MxL</a>. I'm still trying to figure out how to share the source code through that site, though.<br />
<br />
<iframe frameborder="0" height="400" marginheight="0" marginwidth="0" scrolling="no" src="http://www.slideshare.net/slideshow/embed_code/24348144" width="476"></iframe><br />
<br />
<h3>
<b>Update:</b></h3>
I've uploaded a video of the presentation to YouTube:<br />
<div class="separator" style="clear: both; text-align: center;">
<object width="320" height="266" class="BLOGGER-youtube-video" classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000" codebase="http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=6,0,40,0" data-thumbnail-src="http://img.youtube.com/vi/Hp7q0c_u0mY/0.jpg"><param name="movie" value="http://youtube.googleapis.com/v/Hp7q0c_u0mY&source=uds" /><param name="bgcolor" value="#FFFFFF" /><param name="allowFullScreen" value="true" /><embed width="320" height="266" src="http://youtube.googleapis.com/v/Hp7q0c_u0mY&source=uds" type="application/x-shockwave-flash" allowfullscreen="true"></embed></object></div>
<br />BigPigVThttp://www.blogger.com/profile/13822643534037160541noreply@blogger.comtag:blogger.com,1999:blog-8256260706621645238.post-21686966866568443412013-07-11T17:14:00.000-04:002013-07-11T17:14:07.771-04:00Career advice from someone who got lucky<span style="color: #222222; font-family: inherit;">I've got a secret.</span><br />
<span style="color: #222222; font-family: inherit;"><br /></span>
<span style="color: #222222; font-family: inherit;">It's not a bad secret, I didn't kill a hobo or anything. </span><br />
<span style="color: #222222; font-family: inherit;"><br /></span>
<span style="color: #222222; font-family: inherit;">And it's not a particularly well kept secret - lots of folks who know me have heard about it. </span><br />
<span style="color: #222222; font-family: inherit;"><br /></span>
<span style="color: #222222; font-family: inherit;">Although I've been a software development professional for nearly 20 years - my degree was in History.</span><br />
<span style="color: #222222; font-family: inherit;"><br /></span>
<span style="color: #222222; font-family: inherit;">Why am I going public with this confession? Because one of the things which has happened in the course of my software development career is I'm occasionally hit up for career advice - often from people who have a stronger foundation than I did starting off. I'm always happy to oblige with whatever meager insights I can offer; but I sometimes feel I need to qualify it with the fact I fell into this career by happenstance. I'm very glad I did, too, because I've enjoyed myself and had a bit of success in the process.</span><br />
<span style="color: #222222; font-family: inherit;"><br /></span>
<span style="color: #222222; font-family: inherit;">So when I got an email recently from a member of our local user group asking what skills have helped me my career I thought it would be a good topic to cover as I rediscover my blog.</span><br />
<span style="color: #222222; font-family: inherit;"><br /></span>
<span style="color: #222222; font-family: inherit;">It's a pretty open ended question when you think about it. One I would probably better be able to address in a conversation rather than an blog post. But there are a few things that I can put down which might help him out.</span><br />
<span style="color: #222222; font-family: inherit;">The first thing that I thought of was a post I did several years ago that covers a related topic, staying current. The post is <a href="http://bigpigvt.blogspot.com/2009/01/keeping-current.html">http://bigpigvt.blogspot.com/2009/01/keeping-current.html</a>. It's a little dated, obviously, but staying current from a technology standpoint is very important. One update from the original post, too, is my participation in the user group directly lead to my current job. The few presentations I did combined with actively asking questions during others' presentations raised my visibility in the local development community. My current employer knew about me before I knew about them and that gave me an edge in the job hunt. Local user groups are also a key opportunity to build and maintain your professional network.</span><br />
<span style="color: #222222; font-family: inherit;"><br /></span>
<span style="color: #222222; font-family: inherit;">Another thing I believe is nothing beats experience. Getting a programming position if you are not already doing it professionally - after college or during a career change - can be challenging. You're up against a lot of candidates. One way to differentiate yourself is to have a history of actually coding. There's a bit of a chicken and egg issue there, though; how do you get meaningful programming experience if you're not already in a position? During my tenure as a hiring manager I would advise inexperienced candidates that one approach to that dilemma would be to begin contributing to an open source project. It will expose you to programming skills and techniques that you won't get from books or many tutorials. Once your contributions are actually folded into the project you'll be able to cite those contributions to a potential employer. So go to </span><a href="http://www.codeplex.com/site/search/openings">http://www.codeplex.com/site/search/openings</a><span style="color: #222222;">, </span><a href="http://sourceforge.net/people/">http://sourceforge.net/people/</a> or other open source option and get coding!<br />
<span style="color: #222222; font-family: inherit;"><br /></span>
<span style="color: #222222; font-family: inherit;">Finally, what worked for me, and this is definitely because of the non-traditional trajectory my career took, was to be patient and not expect to be programming straight away. The reason I said I have nearly 20 years as a "software development professional" and not as a "programmer" is because I started out doing customer support for a software company, transitioned to being a software analyst, transitioned to a developer analyst and then finally into a full-fledged programmer. For me, the process took about 3 years but it was worth it. My understanding of the software development life cycle is thorough and based on experience.</span><br />
<span style="color: #222222; font-family: inherit;"></span><br />
<span style="color: #222222; font-family: inherit;"><br /></span>
<span style="color: #222222; font-family: inherit;">So now you know my secret. It's just between us, though, because my other secret is nobody really reads this blog. :-)</span>BigPigVThttp://www.blogger.com/profile/13822643534037160541noreply@blogger.comtag:blogger.com,1999:blog-8256260706621645238.post-59025517946478298882013-07-11T16:15:00.000-04:002013-07-11T16:15:12.905-04:00I'm back in the technical saddleAfter a 2 year stint as a software development manager I've decided to focus my career on a technical path again. While I had a fair amount of success in the management role I never got the same level of job satisfaction that I do from working on code and having it run. A podcast I listen to occasionally, <a href="http://www.manager-tools.com/">Manager Tools</a>, described the difference between being an individual contributor and a manager as being like the difference between volcanic eruptions and tectonic plate movements.<br />
<br />
So I'm back as a senior engineer on the team I managed. ASP.NET MVC4, SQL Server 2008R2, jQuery, unit testing... Lots of fodder for blog posts and getting back into doing presentations at user group meetings.<br />
<br />
I'm definitely more of a volcano kind of guy.BigPigVThttp://www.blogger.com/profile/13822643534037160541noreply@blogger.comtag:blogger.com,1999:blog-8256260706621645238.post-34909558060793646612011-04-07T17:14:00.000-04:002011-04-07T17:14:12.734-04:00Input on mobile devices - The long awaited follow up<span class="Apple-style-span" style="font-family: inherit;">Remember my last post? I said I was going to give the <span class="Apple-style-span" style="color: #333333; line-height: 16px;"><a href="http://beta.swype.com/" style="color: #336699;">Swype beta</a> a try? That was back in January. I'm still using it and can't see a reason not to continue with it. It's a very good blend of gesture based input with the keyboard layout I expect. That's not saying it's perfect. I still sometimes struggle with things like entering times because including the colon (:) triggers the auto complete. I also wish entering "your" would allow me to select "you're" from the options of what you might have meant. But these are quibbles and on the whole I'm very happy.</span></span><br />
<span class="Apple-style-span" style="font-family: inherit;"><span class="Apple-style-span" style="color: #333333; line-height: 16px;"><br />
</span></span><br />
<span class="Apple-style-span" style="font-family: inherit;"><span class="Apple-style-span" style="color: #333333; line-height: 16px;">I thought you might like to know.</span></span>BigPigVThttp://www.blogger.com/profile/13822643534037160541noreply@blogger.comtag:blogger.com,1999:blog-8256260706621645238.post-43655324707648010902011-01-18T09:51:00.000-05:002011-01-18T09:51:09.735-05:00Input on mobile devicesSince the last time I posted (I know, way too long ago) I've changed my phone from a Palm Treo 800w (Windows Mobile 6) to a HTC EVO (Android). I've got to say I love my new phone. It does everything I want it to do seamlessly. This includes managing my Google calendar and Gmail, Twitter, Facebook, etc.<br />
<br />
One of the things I was apprehensive about in making the switch, though, was the lack of a physical keyboard. I've always benefited from the tactile response you get from actual buttons. For example, I drive a first generation Prius. In my car the radio station presets are exposed as "buttons" on the center display screen - so no physical buttons. To change the radio station I have to press the "Audio" button on the dashboard (that's a physical button) then look on the screen to press the preset station "button" to change the station.<br />
<br />
Which means taking my eyes off the road.<br />
<br />
While driving.<br />
<br />
So I've learned to hate the on-screen buttons (and to content myself with one radio station that I rarely switch from). What I didn't anticipate with the phone, however, was the fun I could have experimenting with different input methods you get when the physical keyboard is eliminated. <br />
<br />
The EVO comes with a standard on-screen QWERTY keyboard. There are options for having the phone vibrate for each key press (do you call it a key press when there are no keys?) to provide that tactile response I mentioned (although, again, there's no way to determine which "key" you're on without looking at the screen). <br />
<br />
And I was merrily using that when one of my co-workers, <a href="http://twitter.com/pmulc07">Pat</a>, directed me to <a href="http://www.the8pen.com/">8Pen</a>. Now I could try to describe 8Pen, but really you should go to their web site and watch the introductory video. Go ahead and watch it, I'll wait...<br />
<br />
Pretty cool, right? I thought they made a compelling case for ditching the QWERTY keyboard. So I tried it. I installed 8Pen and made a decision to go cold turkey. I knew there would be a learning curve and it might take a while to adapt. It has a number of improvements over the default keyboard. For example, the auto-complete functionality is <i>much</i> than the default. However, after a month without using the default keyboard I decided to ditch 8Pen. It's not that it doesn't work as advertised - it does. But even after a month I was still being slowed down trying to find certain letters.<br />
<br />
Why was that? Why am I measurably faster using a QWERTY keyboard? I think the answer is explained by a blog post I read several years ago. Back when I still read the JoelOnSoftware blog <a href="http://www.joelonsoftware.com/uibook/chapters/fog0000000058.html">this post</a> resonated with me. The central point that I took from it is users have a positive or negative experience with software depending on how that software conforms to their previous experiences. That bias is called the <i>user model</i>. Well, after 25+ years of typing on QWERTY keyboards I'm really efficient at locating letters in that arrangement. Additionally, because I continued to use a QWERTY keyboard throughout the day on my laptop and desktop my assimilation of the 8Pen layout was constantly being subverted. So I cried "uncle."<br />
<br />
The good news is that Pat came to my rescue with a link to the <a href="http://beta.swype.com/">Swype beta</a>. It has the benefit of the QWERTY layout while embracing a gesture based style of input. It's been a week and so far I'm really enjoying it. It's not perfect either, of course, but I'm willing to at least give it a month like I did 8Pen.<br />
<br />
Stay tuned.BigPigVThttp://www.blogger.com/profile/13822643534037160541noreply@blogger.comtag:blogger.com,1999:blog-8256260706621645238.post-57501445202600666922010-07-13T20:16:00.000-04:002010-07-13T20:16:30.044-04:00Turning off the comments on this thingI've decided to turn off comments on the blog because comments were running 8 spam links for every 1 meaningful comment. If you want to send me feedback about a post feel free to send me something on Twitter.BigPigVThttp://www.blogger.com/profile/13822643534037160541noreply@blogger.comtag:blogger.com,1999:blog-8256260706621645238.post-80158482823090712172010-07-06T16:38:00.000-04:002010-07-06T16:38:22.749-04:00Where did FxCop go?I've used FxCop to do code analysis for years now (and brow beat co-workers to use it, too). I've incorporated it into my automated build scripts and use it every time I do a code review. So imagine my dismay when I heard the <a href="http://go.microsoft.com/fwlink/?LinkId=70294">FxCop site</a> was no longer running (I usually get there from the <a href="http://msdn.microsoft.com/en-us/library/bb429476(v=VS.80).aspx">MSDN Library entry about FxCop</a>). I wasn't sure if this was just a case of a dead link, but then I read <a href="http://www.infoq.com/news/2010/06/FXCop-10">this article</a> by Jonathan Allen on InfoQ. Apparently FxCop 1.36 was yanked from the Microsoft Downloads site. Jonathan's article directs the reader to the <a href="http://www.microsoft.com/downloads/details.aspx?displaylang=en&FamilyID=6b6c21d2-2006-4afa-9702-529fa782d63b">Windows 7 SDK</a>. The Microsoft Download site has <a href="http://www.microsoft.com/downloads/details.aspx?displaylang=en&FamilyID=917023f6-d5b7-41bb-bbc0-411a7d66cf3c">an entry for FxCop 10</a> but it turns out that just gets you a readme.txt file instructing you to download the Windows SDK for Windows 7. <br />
<br />
That's not terribly useful. There isn't even a link to where to get the Windows 7 SDK in the readme file.<br />
<br />
So thank you to InfoQ and Jonathan for providing the <a href="http://www.microsoft.com/downloads/details.aspx?displaylang=en&FamilyID=6b6c21d2-2006-4afa-9702-529fa782d63b">link</a>.<br />
<br />
BTW, it seems the only reason the older FxCop version was removed was because the functionality FxCop provides is in some versions of VS2010. This is going to have an impact on my automated build scripts so I expect I'll be following the advice from <a href="http://www.paraesthesia.com/archive/2010/03/29/updating-your-continuous-integration-build-to-run-fxcop-from-vs2010.aspx">this blog post</a> from Travis Illig's blog at some point - so thanks to him, too.BigPigVThttp://www.blogger.com/profile/13822643534037160541noreply@blogger.com