Using libgit2sharp with LINQPad?
Asked Answered
A

6

6

I have the LINQPad version with NuGet and I add libgit2sharp but this relies on a another (native) dll.

I've tried:

  • Copying them my systemdirectory.
  • Put them in a separate directory that I've added to the path.
  • Put them in LINQPads plugin directory.
  • Copy them when I run the query to Assembly.GetExecutingAssembly().Location

I'm just trying to read the log with this library and having it as a snippet in LINQPad would be neat though I suppose I could make it a console application if all else fails.

Anyone used libgit2sharp with LINQPad and can explain how to make them play nice together?

Androclinium answered 7/6, 2013 at 11:32 Comment(2)
Is there an error from LinqPad? I'm not quite sure of what problem you are having.Oomph
Yeah, Unable to load DLL 'git2-9d9fff3' (the one I copied around in my tests)Androclinium
I
7

Putting the dll into a folder that is in your path or adding the location of your dll to your path should work (and works for me)

Perhaps your changes have not taken effect. Try closing and re-opening LinqPad or if that fails, log out and back into windows.

Inigo answered 7/6, 2013 at 12:58 Comment(1)
I feel stupid. I copied the dll to one of my path directories where I've always kept UnxUtils, sysinternals binaries etc. Just assumed LINQPad would find it if that had worked but restarting LINQPad was required. Thanks a bunch.Androclinium
B
5

EDIT: LINQPad again supports LibGit2Sharp out of the box (as of LINQPad 5.10.02 - in beta at time of writing). No workarounds are now required.

Unfortunately, this is broken again in LibGit2Sharp v0.22. This package no longer contains the native binaries in a subfolder beneath where LibGit2Sharp.dll is located in /libs. Instead, they are in a separate dependent NuGet package which relies on patching a project file. As LINQPad doesn't use project files, this fails.

You can work around this by adding an initialization method as suggested in other answers to populate the PATH variable with the native folder location. The following code will work without modification on any machine with the current LibGit2Sharp:

void Main()
{
   ... your query here...
}

static UserQuery()
{
   const string pathEnvVariable = "PATH";
   char slash = Path.DirectorySeparatorChar;
   char pathSep = Path.PathSeparator;

   // The correct native binary file is located under a folder ending in
   // "windows\x86" or "windows\amd64" or "win7-x86\native" or "win7-x64\native".
   // This may change in later LibGit2Sharp releases.
   string nativeStem1 = $"{slash}windows{slash}{(IntPtr.Size == 8 ? "amd64" : "x86")}";
   string nativeStem2 = $"{(IntPtr.Size == 8 ? "-x64" : "-x86")}{slash}native";

   // Locate the root folder in the NuGet package. This contains folders for the
   // main package (LibGit2Sharp) plus dependencies (LibGit2Sharp.NativeBinaries).
   var nugetRoot = new FileInfo (typeof (Repository).Assembly.Location)
      .Directory.Parent.Parent.Parent;

   var nativeBinaryPath = nugetRoot
      .GetFiles ("*.dll", SearchOption.AllDirectories)
      .Single (d => d.DirectoryName.EndsWith (nativeStem1, StringComparison.OrdinalIgnoreCase) ||
                    d.DirectoryName.EndsWith (nativeStem2, StringComparison.OrdinalIgnoreCase))
      .Directory
      .FullName;

   string currentPaths = Environment.GetEnvironmentVariable (pathEnvVariable);

   if (!(pathSep + currentPaths + pathSep).ToUpperInvariant().Contains
      (pathSep + nativeBinaryPath.ToUpperInvariant() + pathSep))
   {
      Environment.SetEnvironmentVariable (pathEnvVariable, currentPaths + pathSep + nativeBinaryPath);
   }
}

Note that you don't need to explicitly call this method because it's in a static constructor.

Another workaround would be to publish another LibGit2Sharp package on NuGet that included the native binaries in the expected locations under where LibGit2Sharp.dll is located (NativeBinaries\x86\git2-785d8c4.dll and NativeBinaries\amd86\git2-785d8c4.dll) - download LibGit2Sharp 0.21.0.176 for an example.

Bonnette answered 9/10, 2016 at 7:11 Comment(3)
Thanks Joe. For some reason my LinqPad seems to be running the query from the TEMP folder. This means it blows up with InvalidOperationException: Sequence contains more than one matching element. when getting the NuGet root. When I change this line to this it works: var nugetRoot = new DirectoryInfo(Path.Combine(localAppData, "LINQPad", "NuGet.FW46"));Glower
Is this broken again? I'm trying to use LINQPad 5.36.03 with LibGit2Sharp 0.26 and getting DllNotFoundExceptionSupply
Yes, the latest libgit2sharp is broken for good in LINQPad 5. The workaround is to download version 0.25.4 or earlier. The good news is that it will work again in LINQPad 6 under .NET Core.Bonnette
C
3

I ended up adding the related path at runtime using:

void SetUpNativeBinaries(){
    var appDataLocal = Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData);
    var packageVersion = "LibGit2Sharp.0.14.0.0";// may read from PackageInfo
    var processorArchitecture = IntPtr.Size==8?"amd64":"x86";
    var libgitNativeBinaryPath = Path.Combine(appDataLocal, "LINQPad", "NuGet", "LibGit2Sharp", packageVersion, "NativeBinaries", processorArchitecture);
    libgitNativeBinaryPath.Dump();

    var pathEnvVariable = "PATH";
    var currentPaths = Environment.GetEnvironmentVariable(pathEnvVariable);
    var combinedPaths = String.Format(
        System.Globalization.CultureInfo.InvariantCulture,
        "{0}{1}{2}",
        libgitNativeBinaryPath,
        Path.PathSeparator,
        currentPaths);

    Environment.SetEnvironmentVariable(pathEnvVariable, combinedPaths);
}

Saving that as "C# Program" you can start right away:

void Main()
{
    SetUpNativeBinaries();
    var repoWorkingDir = @"C:\temp\libgit2_repo";
    var repo = new Repository(repoWorkingDir);

    repo.Config.Dump();
    repo.Branches.Dump();
    repo.Index.RetrieveStatus().Dump();
    //...
}

Update There is a closed issue and the fix is shipped with since release 0.14.1.0

Commie answered 18/9, 2013 at 9:1 Comment(0)
P
3

The amazing @mbx stood up and helped us make this happen.

Thanks to him, the next release of LibGit2Sharp NuGet package (v0.15.0) will directly work from within LinqPad.

Update:

LibGit2Sharp NuGet v0.14.1 package contain this fix and is now available for download.

Prater answered 21/9, 2013 at 14:58 Comment(1)
Version 0.22.0 of the LibGit2Sharp NuGet package isn't working in version 5.08.01 of LINQPad.Facies
F
2

Neither the NuGet package as-is nor mbx's answer worked for me for version 0.22.0 of the LibGit2Sharp NuGet package and version 5.08.01 of LINQPad.

I modified the method in mbx's answer to be the following:

void SetUpLibGit2SharpNativeBinaries()
{
    string libGit2SharpNativeBinariesPath = @"C:\Users\kevitt\AppData\Local\LINQPad\NuGet.FW46\LibGit2Sharp\LibGit2Sharp.NativeBinaries.1.0.129\libgit2\windows\x86";

    string pathEnvVariable = "PATH";
    string currentPaths = Environment.GetEnvironmentVariable(pathEnvVariable);

    IEnumerable<string> paths = currentPaths.Split(';');

    if (!paths.Contains(libGit2SharpNativeBinariesPath))
    {
        var combinedPaths = String.Format(
            System.Globalization.CultureInfo.InvariantCulture,
            "{0}{1}{2}",
            libGit2SharpNativeBinariesPath,
            Path.PathSeparator,
            currentPaths);

        Environment.SetEnvironmentVariable(pathEnvVariable, combinedPaths);
    }
}

Note that this almost certainly won't work for anyone else as-is as you'll need to replace my Windows login name with your own at minimum in the value assigned to the string variable libGit2SharpNativeBinariesPath.

Also, libGit2SharpNativeBinariesPath (corresponding to the libgitNativeBinaryPath string in mbx's code) didn't seem to now be something that could be (easily) generated as in mbx's code so you may need to determine the path yourself.

Facies answered 5/10, 2016 at 20:55 Comment(6)
Replacing C:\Users\kevitt\AppData\Local with %LOCALAPPDATA% should make the script more generic. You'll still be hard coded onto a fixed version of LibGit2Sharp.NativeBinaries though. I just added %LOCALAPPDATA%\LINQPad\NuGet.FW46\LibGit2Sharp\LibGit2Sharp.NativeBinaries.1.0.129\libgit2\windows\x86 to my PATH and that seems to have done the trick.Glower
@KevinKuszyk I actually tried your suggestion and it doesn't work. Mind trying it yourself?Facies
So now I'm confused. This worked last week, but it's broken again today. I'll investigate some more and post an update when I have one.Glower
I'm making progress. It seems %LOCALAPPDATA% doesn't work in LinqPad, but var localAppData = Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData) does.Glower
@KevinKuszyk As Joe Albahari mentioned in his comment to you on his answer this question, he's going to 'fix' this in LINQPad; more details here.Facies
Yes, I saw that this morning. I've added Joe's workaround to our scripts. I'll take it out when the new version of LinqPad ships.Glower
D
0

Worked for me: copy git2-785d8c4.dll into the same directory as LibGit2Sharp.dll and restart LINQPad.

copy %LOCALAPPDATA%\LINQPad\NuGet.FW46\LibGit2Sharp\LibGit2Sharp.NativeBinaries.2.0.267\runtimes\win-x86\native\git2-785d8c4.dll %LOCALAPPDATA%\LINQPad\NuGet.FW46\LibGit2Sharp\LibGit2Sharp.0.26.0\lib\net46

(LibGit2Sharp.0.26.0, LINQPad 5.36.03)

Demoss answered 13/6, 2019 at 21:54 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.