GitLink 2.0 – making .NET open source accessible!

I am very proud to announce GitLink 2.0, the tool that will make open source code more accessible! This release is a major release introducing many new features and improvements. One of the improvements is support for more providers than GitHub, so I have renamed GitHubLink to GitLink.

First things first: this release wouldn’t be what it is now without the help of my friend Peter Kiers who saw the potential and lifted the product to a higher level.

Supporting more providers

As soon as we released GitHubLink, it went popular among open-source developers on GitHub. However, some people requested support for other providers such as BitBucket. This gave us the idea to create a generic approach where we could automatically detect the provider and find the right information. As of now, the following providers are supported:

  • BitBucket
  • GitHub

Are you interested in supporting a provider? Help us out with a pull request, it’s really easy!

Supporting more project types

GitHubLink supported both C# and Visual Basic projects. Starting with GitLink 2.0, all project types that Visual Studio can load are supported such as C++ and F#.

Improved performance

One of the downsides of GitHubLink was that it downloaded the whole repository in order to retrieve the latest commit SHA. GitLink 2.0 automatically determines whether there is a local .git folder. If so, it won’t even go to the official url to retrieve the latest commit but will use the local repository. If there is no local .git file, GitLink 2.0 will only fetch the latest commit and will no longer download any files from the remote repository resulting in much better performance.

Introducing PDB file verifications

Starting with GitLink 2.0, all PDB files are now verified before being updated. This means that GitLink checks whether all files inside the PDB file are actually available and contain the right hash.

Removing the F# and SourceLink dependencies

GitHubLink heavily relied on SourceLink, an F# implementation to update the PDB files to allow a custom source server. It was however hard to combine the world of F# and C# and we always had to ship the 2 assemblies with GitHubLink. In GitLink 2.0, the dependencies are no longer required and all logic is translated to C#. This improvement saves about 500 kb on the final GitLink assembly size.

How to get GitLink

You can download GitLink 2.0 here. It is also available on NuGet and Chocolatey. Note that if you have used GitHubLink in the past, we will be keeping compatibility packages for that until version 3.0. It’s best to update to GitLink as soon as possible.

Workspace management in C#

Recently I was working on a few projects that required the management of workspaces. Workspaces is a fancy term for a document, a list of documents or anything in between. I noticed that I was implementing the same logic over and over again so decided to create a library (and NuGet package) from the experiences.

The Orc.WorkspaceManagement package is currently in prerelease but I use it in several products.

The workspace management library makes it easy to manage workspaces. The main component is the IWorkspaceManager that contains the current workspace and allows to load or save a workspace. Note that this library does not force you to use a specific workspace location of any sort, so it can even be a database or server call to read / write the workspace.

Below is an overview of the most important components:

  • IWorkspace => the actual workspace object
  • IWorkspaceManager => the workspace manager with events and management methods
  • IWorkspaceInitializer => allows customization of initial settings of a workspace
  • IWorkspaceReader => reads a workspace from a location
  • IWorkspaceWriter => writes a workspace to a location

Creating a workspace

A workspace is a model that can be implemented by the developer and must implement the IWorkspace interface. The most convenient way to implement a workspace is by deriving from the WorkspaceBase class:

Creating a workspace initializer

When a workspace manager is created, it doesn’t contain anything. The IWorkspaceInitializer interface allows the customization of that state.

By default the following initializers are available:

  • EmptyWorkspaceInitializer => initializes nothing, this is the default
  • DirectoryWorkspaceInitializer => First checks if there is an app config setting called DataLocation. If so, it will use that. If not, it will fall back to %AppData%\[assembly company]\[assembly product]\data. Then it will also check if a command line directory is passed (first argument). If so, all previous will be overriden by the command line directory.

To create a custom workspace initializer, see the example below:

Next it can be registered in the ServiceLocator (so it will automatically be injected into the WorkspaceManager):

Make sure to register the service before instantiating the IWorkspaceManager because it will be injected

Creating a workspace reader service

Workspaces must be read via the IWorkspaceReaderService. The workspace manager automatically knows when to read a workspace. First, one must create a workspace reader as shown in the example below:

Next it can be registered in the ServiceLocator (so it will automatically be injected into the WorkspaceManager):

Creating a workspace writer service

Next it can be registered in the ServiceLocator (so it will automatically be injected into the WorkspaceManager):

Retrieving a type instance of the workspace

The library contains extension methods for the IWorkspaceManager to retrieve a typed instance:

Building Git repositories containing sub modules with Continua CI

Today I wanted to add a repository to the build server that contains submodules. The submodules are required because I prefer to share code via shared projects so they will always be compiled for the right platform as you can read here.

When you add a repository to a project or configuration in Continua CI, you can add authentication. However, the sub modules won’t use the same authentication which means that the submodule can never be retrieved. To solve this issue, use the steps below.

Create separate build server account (optional)

I prefer to create a read-only account for build servers so it can never screw anything up. For private projects I use Bitbucket so I created a new buildserver account and added it to the team with read-only access.

Create _netrc file on the server

The _netrc file can be used to provide default credentials to a server when they aren’t provided on the actual repository. I prefer to keep everything together so I followed the following steps:

  1. Create directory C:\Continua\Auth
  2. Create a %HOME% system variable pointing to this path (I prefer using a shared path for %HOME% so it is accessible to all users)
  3. Create the _netrc file (note that there is no extension) with the following content:

machine [host]
login [buildserveraccount]
password [password]

for example:

machine bitbucket.org
login mybuildserveraccount
password mypassword

Now Continua CI will be able to pull the submodules as well.