blog, downloads comments edit

Over the years I’ve pushed out a lot of little downloads, source, and code snippets on my blog. Yesterday I finally got all of that moved out of the various little dump sites on disks and in private repos and into GitHub.

I’ll continue updating links and adding things when I find them, but you should be able to see most everything there:

  • Repositories (contain more fully-fledged projects and things that can be built)
  • Gists (contain one-off files and snippets)

It was kind of a blast from the past looking at some of that stuff. I can see how I’ve changed styles and improved. Who doesn’t look at stuff they wrote 10 years ago and shake their head?

I could also see where I used certain tools or tech back then and don’t anymore. Like… remember when T4 didn’t exist and CodeSmith was the way to generate things? Anyone remember the Prototype JS library? Building with NAnt?

I can’t promise all of it will compile as-is. For example, I see a lot of VS 2003 and VS 2005 solutions in there. Will that straight-up convert to VS 2015+? Your guess is as good as mine.

Anyway, it felt good to get things centralized, even if it’s not all stellar code.

personal, family, humor comments edit

Captain’s Log: December 9, 2016.

School has been canceled for the second day in a row. The school district claims this is due to “potential safety concerns” for people coming in from higher elevations where there may be ice and snow, but our vessel is less than one mile from the school and there is nothing on the ground, nor is there anything falling from the heavens.

I think it’s a plot.

Of the regular crew of three, only two of us remain on board. The XO has gone on an away mission to work leaving me here with the first mate. I am attempting to address my standard duties but the first mate, being (what I understand is) a typical six-year-old, is fairly needy and in a constant attempt at mutiny.

I have considered throwing her in the brig but given the smallish size of the vessel, such sentences don’t last very long and definitely don’t have the desired effect. I have, however, informed her that if she continues her mutinous trend that her very life may be in danger. We’ll see how long she lasts when I throw her overboard into the icy waters.

There is constant rumblings of “nothing to do” and “super bored,” the suggested remedy for which is, naturally, “more television.” I have suggested several alternatives based on the diversions available on board, including - but not limited to - Barbies, Magnatiles, LEGOs, art projects, Playmobil make believe, stuffed animals, play kitchen, tea parties, dress up, and other various combinations of toys with inventive scenarios. None of these placate the desires of the restless first mate.

I find interruptions from the first mate come in at regular 15 minute intervals, almost as though she has a timer set somewhere. I will log such an interruption as an example here:

I was sitting in my office attempting to work through the daily reports. As I was sitting here, I heard a small but growing call.


I raced from my office to find the cause of the call. The first mate was sitting eating breakfast.

“What is it, Phoenix? Are you hurt? With the amount of screaming, you’d best be really injured or bleeding or something.”

“I just wanted to tell you I love you.”

“NO. No, you don’t get to just screeeeam for no reason and then try to get away with it. Finish eating your breakfast.”

This sort of interruption occurs, as mentioned, fairly regularly. Either a call comes in or the first mate enters unannounced to make a nonsensical request.

I would ship her off to a neighboring vessel to play with one of her crewmates but I’m unfamiliar with the other ships’ captains so that’s not really an option. I believe one of her crewmates lives across the street. I will make a note to become more familiar with that vessel so I am not caught by surprise like this again.

Should our boat sink within the next few hours, this log explains the brewing storm being faced. There is a high probability that the first mate’s mutiny will succeed before the XO returns. When I am done with this log I will raise a distress call on the radio to see if any help may be coming. I have little hope.

teamcity, net, build comments edit

I’ve run across more than my fair share of times, particularly early on in a project, where I need to flush the NuGet package cache for my TeamCity build agents. This has usually involved connecting to each agent in Remote Desktop and doing some manual commands or delete operations.

No more!

Instead of manually flushing the NuGet package cache, create a build configuration that does it for you.

Create a build configuration that isn’t attached to any source. The point of this build is to execute a script as the build user so the appropriate package cache gets cleared.

In the build configuration, add a single “Command Line” build step. Set the working directory to %teamcity.tool.NuGet.CommandLine.DEFAULT%\tools - this is where TeamCity has its default NuGet command line installation. For the custom script, put this:

echo ##teamcity[buildNumber '%build.counter% (']
nuget.exe locals -clear all

The first line sets the build number so you can see which agent ran it easily from the top-level dashboard. The build number will look like #24 (my-agent-name) The second line runs the actual NuGet package cache clearing command to ensure all the various cache locations get purged.

Now all you need to do is queue a build and target the agent you want to flush - it runs in a second or two and you’re done. No more need to connect and do it all manually.

halloween, costumes comments edit

This year we had 184 trick-or-treaters. It’s a huge improvement over last year, but not one of the larger years.

2016: 184

Average Trick-or-Treaters by Time Block

Year-Over-Year Trick-or-Treaters

Halloween was on a Monday and, while it had rained earlier, was pretty clear otherwise.

This year they started doing a “Harvest on Main Street” event in my city which had an unknown impact on the trick-or-treat count. I know some friends who went to this instead of going door-to-door. It looked fun, so if they do it next year we may have to check it out. An indirect impact of this, of course, is that it means fewer people available to hand out candy, which could cause fewer kids to travel down certain streets.

We shut down at 8:00p to get Phoenix into bed (since that’s bedtime). I foresee this being the case for a few more years. The 8:00p - 8:30p range has always been where things taper off anyway, so it’s not a major impact.

Cumulative data:

  Time Block
Year 6:00p - 6:30p 6:30p - 7:00p 7:00p - 7:30p 7:30p - 8:00p 8:00p - 8:30p Total
2006 52 59 35 16 0 162
2007 5 45 39 25 21 139
2008 14 71 82 45 25 237
2009 17 51 72 82 21 243
2010 19 77 76 48 39 259
2011 31 80 53 25 0 189
2013 28 72 113 80 5 298
2014 19 54 51 42 10 176
2015 13 14 30 28 0 85
2016 1 59 67 57 0 184

Our costumes this year:

I didn’t actually pick a specific character this year, I just happened to like the pattern I found. I learned, however, that saying, “I’m a safari guy” or something to that effect wasn’t satisfactory to most people, who really wanted me to be a character. I had a few people think I was Dr. David Livingstone (“Dr. Livingstone, I presume.”) That’s fine, but it was interesting to see people struggle to attach a specific person to the outfit.

It makes me wonder how one might wear, say, just a historical reproduction costume or an original steampunk costume, and have that just work without it having to be someone specific. You can do that as a witch or a ghost, why not with other costume types?

I walked Phoenix around the neighborhood to do the trick-or-treating while Jenn handed out candy. This year Phoenix was far more into it (plus, no rain) so we went all over the neighborhood. At one point I actually had to pull out Google Maps because I couldn’t see the street signs and had gotten all turned around. We also nearly hit some houses twice since Phoenix really didn’t want to follow any orderly plan of attack.

Next year I think I’ll approach this in a more prepared fashion, with a map where I can mark down which street(s) we’ve hit and maximize the candy retrieval operation.

build, github, powershell, tfs comments edit

Git has a specific document on how to migrate Perforce to Git. The instructions here are based on the content there as well as some other “gotchas” and articles I ran into.

I’m using the git-p4 command rather than Perforce Helix Git Fusion. Git Fusion is a whole separate proxy-style service you need to set up that allows you to use Git clients to interact with a Perforce source control system. This makes it easy to migrate to a real Git back end, but it also is far more complex to set up for a one-time migration operation.

Oh, and you’ll probably notice I’m not really a Perforce user. I was tasked with migrating some Perforce stuff into Git recently and this is the process I pieced together. I may say some stuff that’s like, “Well, duh!” to folks who use Perforce more often.

Install Windows Tools

The tool installation and setup is based on the instructions here.

Chocolatey Install

If you use chocolatey, install is pretty quick.

choco install git
choco install python --version 2.7.11
choco install p4

Manual Install

You can manually install the requisite tools by downloading them and installing them from their respective pages:

Enable git-p4

The git-p4 Python script is installed when you install Git for Windows but it isn’t enabled by default. Run this command to add the p4 alias to git:

git config --global alias.p4 !"python 'C:/Program Files (x86)/Git/mingw32/libexec/git-core/git-p4'"

Once you have that enabled, you should be able to run git p4 and see results like this:

PS C:\Users\yourusername> git p4
usage: C:/Program Files (x86)/Git/mingw32/libexec/git-core/git-p4 <command> [options]
valid commands: clone, rollback, debug, commit, rebase, branches, sync, submit
Try C:/Program Files (x86)/Git/mingw32/libexec/git-core/git-p4 <command> --help for command specific help.
PS C:\Users\yourusername>

Set Perforce Environment Variables

The Perforce client needs environment variables so it knows which source control system to use, who you are, etc. You must have an account on the Perforce system to do this migration. Unlike Git, you can’t just anonymously clone the repo. If you want to try this out, you can get a free account on the public Perforce server and follow along cloning a public repo.

The example below shows use of the public Perforce depot.

$env:P4PORT = ''
$env:P4USER = 'yourusername'
$env:P4PASSWD = 'yourpassword'
set P4USER=yourusername
set P4PASSWD=yourpassword

Clone the Perforce Repo with git p4

Cloning the Perforce repo is pretty simple, but making sure the branches in Perforce correctly map to branches in Git is a bit harder. The typical clone looks like this:

git p4 clone --detect-branches //guest/perforce_software/p4jenkins@all .

This example clones the Jenkins/Perforce integration project into the current directory. The @all specifier means all of the changesets through history will be brought in rather than just the latest.

If there are more complex branching strategies at play, this page on the Git site explains how to explicitly map folders to branches and so on.

Once the repo is cloned, Git sees the Perforce “repo” as a “remote” called “p4” that it can use to push changes back. Any branches it sees are attached only with the “p4” remote that it has added. We’ll fix that later.

Add a Remote to the New Git Repo

The way Git knows where to push the cloned data is by setting up a remote. Create the destination Git repo on the server and then…

git remote add origin
git remote add p4

The first remote is added and is the usual/standard remote for a Git repo.

The second remote is added and called “p4” because the branches brought over are tied to a “p4” remote which is not actually defined in the repo by default. By adding this remote as a stand-in, you allow Git to bypass some logic that will fail when you try to move branches over when it sees “p4” doesn’t exist.

Bring Branches to the New Git Repo

As noted earlier, branches that the import creates are still associated with the “p4” remote. We need to bring those over to the new repo.

Here’s a Powershell script to do that:

(& git branch -r).Split([Environment]::Newline) |
%{ $_.Trim() } |
Where-Object { $_ -notlike "/master" -and $_ -like "p4/" } |
%{ (& git checkout --track "$_") }

This script…

  1. Uses the Git command line to list all the remote branches in the cloned local repository.
  2. Splits the output of the command line so Powershell can process each listed branch.
  3. Trims off leading and trailing whitespace on each listed branch.
  4. Finds all the branches that aren’t “master” (because that’s already available in the destination repo) and that start with “p4” (indicating the branch originated in Perforce).
  5. Checks out each of the branches from Perforce and starts tracking them in your local repository.

By tracking each of the “p4” branches in your local repo, it allows you to push those branches to the new Git remote repo. If you don’t do that, the branches won’t make the migration.

Push to the New Git Repo

Push the code, history, and branches all to the new repo.

git push -u origin --all

Remove the Fake p4 Remote

You don’t need the fake “p4” remote that the “git p4” command added since the branches are all moved over now. Remove it to avoid confusion.

git remote rm p4