Adventures in vs Extension Updates

While at //build I was inspired to update my extensions to support VS 2017. I meant to do it last year, but got distracted. The process was really simple, and is outlined on the new hotness that is MS Docs. It took me about 10 minutes to get it all configured an tested. But then…I was sidelined by my CI config.

For some reason, my AppVeyor builds were failing. They were clearly pulling the latest from my repo, but for some reason, the nuget restore stopped working. I probably should’ve googled the issue, and I think I did, but I was asking the wrong questions. I finally gave up and manually configured the build via the GUI, and then exported that config to YAML. When I went to do the next extension, I finally realized what the problem was. I used the exact same exported YAML, and got the exact same initial errors with the nuget restore.

Googling “appveyor not using yaml” led me to this help article. I still don’t understand why permissions were an issue to read the appveyor.yml, when it was clearly reading an updated csproj file. But I do now have extensions that support VS 2017.


Data Driven

This video absolutely changed my life. My friend and mentor showed it to me in the beginning of 2015. The early experiences of Etsy immediately resonated with me. And the concept of geometric growth being outside of the control of the business was something that I had never before considered, but absolutely made sense.

Don’t pick projects based on what’s cool, pick projects that make sense to the company.


Product Development Manifesto

Five years ago, I ambitiously applied internally for a job as Director of Product Development. I agree that my qualifications were not appropriate for such a position. To overcome that, however, I wrote this manifesto, to show how I would handle the problems faced by that team.

When I stumbled across this the other day, I was afforded a chance to see if any of my plans had been adopted. Some have, most haven’t. When I wrote that piece, I was a dev manager. Since then I’ve been a Sr Dev and a Software Architect. I’m now back in the position of manager, and I’m happy to see that my personal views haven’t substantially changed. Of course, my opinions about Scrum, testing, and APIs have evolved, but my management approaches are consistent. Trust, Respect, and Accountability. Those three pillars are the foundation of good leadership.

If you have a chance, please read it. Send any comments to me on Twitter at @clintcparker.


C# Obfuscation

You can use the underscore to write ridiculous code.

__ is a valid class name. __ is a valid namespace. __() is a valid method. And, __ is a valid property.

I stumbled upon this a few years ago , but hadn’t gotten around to writing it down. It’s really fun to play with. I thinkt the next step is to create an obfuscator extension.

Here’s a simple class from when I was teaching intro to C# and demonstrating async and await.

using System.IO;
using System.Threading.Tasks;

namespace A_A.Library
{
    public class FileAccess
    {
        public async Task<int> GetLength(string filePath)
        {
            var sr = new StreamReader(filePath);
            var chars = sr.ReadToEnd();
            return chars.Length;
        }

        public async Task<int> GetLines(string bigTxt)
        {
            int lines = 0;
            var sr = new StreamReader(bigTxt);
            while (!sr.EndOfStream)
            {
                await sr.ReadLineAsync();
                lines++;
            }
            return lines;
        }
    }
}

Here’s it is again, obfuscated. Still compiles, still valid C#.


using System.IO;
using System.Threading.Tasks;

namespace __
{
    public class ___
    {
        public async Task<int> ____(string ___)
        {
            var _ = new StreamReader(___);
            var __ = _.ReadToEnd();
            return __.Length;
        }

        public async Task<int> _____(string ___)
        {
            int _ = 0;
            var __ = new StreamReader(___);
            while (!__.EndOfStream)
            {
                await __.ReadLineAsync();
                _++;
            }
            return _;
        }
    }
}

Thanks for reading.

P.S. Who want’s to help me write the obfuscator?


Why Git Works Where TFVC Doesn't

We’re in the process of moving to git right now, and one of the main questions I get is how will this ACTUALLY be any better than TFVC. (The other question is how much longer before we’re fully moved to git? Which warrants its own piece.)

See, we’ve tried “branching” in TFVC, and it only caused us more pain. So there is some legitimacy to this question.

We were doing some hard core bastardized scrum, and had successfully split our department into scrum teams. Who would work on all kinds of stuff each sprint. Maybe half the team was working on a global refactoring of a pattern, maybe the other was working on migrating some key workflows from our old static classes to new workflows leveraging dependency injection. Either way, different work with different timeframes.

Because we’re agile, we need to be able to work on lots of different things at any given time. But branching in TFVC is different than it is in git. A branch in TFVC is immediately available to everybody to see. And it never really goes away, but you can hide it (cool!). But you can’t use that name again (bummer).

Since it never goes away, and we didn’t want to be constantly reminded of our bad branch naming, we picked a very generic naming scheme. Git branching would say be specific with you’re development branch names. But ours were Work-1, Work-2, .etc. We had about 10 teams at that point, and we ended up with 32 “work” branches.

Ok, 32, not too bad. But it was. 32 is not enough for the number of features & bug fixes being developed by 10 (and growing) teams. We probably needed 100-500 to have actually been successful. But with generic names like work-2, it’s hard to keep track of ownership. So we stopped at 32.

And this is where it got messy.

Scenario: The team is working on three different things in Work-14. One is done, while two are in progress. That whole branch has to be brought in now. Because that one completed feature is made up of 100 different changesets over six weeks. So we can’t just cherry pick that one feature. And now we’ve brought in two half-done features into mainline. We’re constantly testing mainline, so we feel OK about this, but the reality is that it’s not mainline that causes the problem. Another team just got two half done projects dumped into their branch, because they rebased from mainline. And not just one other team, but nine. And then they’re all propagating that back out to everybody else.

In the end, the chaos comes from the unfinished work being forced into everybody’s “clean” branches. But we’re actually paying extra for that chaos, because we now have to constantly rebase and merge branches, which takes time and understanding of a myriad of incongruent changes.

Earlier I said we’ve “tried” branching. We did. And then we abandoned it. We still have the chaos, but not the extra cost. Everybody commits to mainline, it is constantly under test, and we ship often. Builds break, and it affects everybody, but it gets resolved quickly.

I’m of the belief that is has made our developers better, knowing the impact of a bad commit. But it isn’t easy.

So we’re switching to git. And we can have as many branches as we want. And they can be local. And they can have good names. And they can be deleted. And we can still commit to mainline if we want to.