diff --git a/SourceLink.sln b/SourceLink.sln index 4cd92582..544df8a9 100644 --- a/SourceLink.sln +++ b/SourceLink.sln @@ -29,6 +29,8 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.SourceLink.GitHub EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.SourceLink.Vsts.Git.UnitTests", "src\SourceLink.Vsts.Git.UnitTests\Microsoft.SourceLink.Vsts.Git.UnitTests.csproj", "{60C82684-6A13-4AEF-A4F5-C429BEDE1913}" EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.Build.Tasks.Git.Operations", "src\Microsoft.Build.Tasks.Git.Operations\Microsoft.Build.Tasks.Git.Operations.csproj", "{BC24CED9-324E-4AF9-939F-BDB0C2C5F644}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -87,6 +89,10 @@ Global {60C82684-6A13-4AEF-A4F5-C429BEDE1913}.Debug|Any CPU.Build.0 = Debug|Any CPU {60C82684-6A13-4AEF-A4F5-C429BEDE1913}.Release|Any CPU.ActiveCfg = Release|Any CPU {60C82684-6A13-4AEF-A4F5-C429BEDE1913}.Release|Any CPU.Build.0 = Release|Any CPU + {BC24CED9-324E-4AF9-939F-BDB0C2C5F644}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {BC24CED9-324E-4AF9-939F-BDB0C2C5F644}.Debug|Any CPU.Build.0 = Debug|Any CPU + {BC24CED9-324E-4AF9-939F-BDB0C2C5F644}.Release|Any CPU.ActiveCfg = Release|Any CPU + {BC24CED9-324E-4AF9-939F-BDB0C2C5F644}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE diff --git a/eng/SignToolData.json b/eng/SignToolData.json index 6c18b2ca..3d71fea3 100644 --- a/eng/SignToolData.json +++ b/eng/SignToolData.json @@ -4,23 +4,27 @@ "certificate": "MicrosoftSHA2", "strongName": "MsSharedLib72", "values": [ - "bin/Microsoft.Build.Tasks.Git/net461/Microsoft.Build.Tasks.Git.dll", - "bin/Microsoft.Build.Tasks.Git/net461/*/Microsoft.Build.Tasks.Git.resources.dll", - "bin/Microsoft.Build.Tasks.Git/netcoreapp2.0/Microsoft.Build.Tasks.Git.dll", - "bin/Microsoft.Build.Tasks.Git/netcoreapp2.0/*/Microsoft.Build.Tasks.Git.resources.dll", + "bin/Microsoft.Build.Tasks.Git.Operations/net461/Microsoft.Build.Tasks.Git.dll", + "bin/Microsoft.Build.Tasks.Git.Operations/net461/Microsoft.Build.Tasks.Git.Operations.dll", + "bin/Microsoft.Build.Tasks.Git.Operations/net461/*/Microsoft.Build.Tasks.Git.resources.dll", + "bin/Microsoft.Build.Tasks.Git.Operations/netcoreapp2.0/publish/Microsoft.Build.Tasks.Git.dll", + "bin/Microsoft.Build.Tasks.Git.Operations/netcoreapp2.0/publish/Microsoft.Build.Tasks.Git.Operations.dll", + "bin/Microsoft.Build.Tasks.Git.Operations/netcoreapp2.0/publish/*/Microsoft.Build.Tasks.Git.resources.dll", "bin/Microsoft.Build.Tasks.Tfvc/net46/Microsoft.Build.Tasks.Tfvc.dll", "bin/Microsoft.SourceLink.Common/net461/Microsoft.SourceLink.Common.dll", "bin/Microsoft.SourceLink.Common/net461/*/Microsoft.SourceLink.Common.resources.dll", - "bin/Microsoft.SourceLink.Common/netcoreapp2.0/Microsoft.SourceLink.Common.dll", - "bin/Microsoft.SourceLink.Common/netcoreapp2.0/*/Microsoft.SourceLink.Common.resources.dll", + "bin/Microsoft.SourceLink.Common/netcoreapp2.0/publish/Microsoft.SourceLink.Common.dll", + "bin/Microsoft.SourceLink.Common/netcoreapp2.0/publish/*/Microsoft.SourceLink.Common.resources.dll", "bin/Microsoft.SourceLink.GitHub/net461/Microsoft.SourceLink.GitHub.dll", "bin/Microsoft.SourceLink.GitHub/net461/*/Microsoft.SourceLink.GitHub.resources.dll", - "bin/Microsoft.SourceLink.GitHub/netcoreapp2.0/Microsoft.SourceLink.GitHub.dll", - "bin/Microsoft.SourceLink.GitHub/netcoreapp2.0/*/Microsoft.SourceLink.GitHub.resources.dll", + "bin/Microsoft.SourceLink.GitHub/netcoreapp2.0/publish/Microsoft.SourceLink.GitHub.dll", + "bin/Microsoft.SourceLink.GitHub/netcoreapp2.0/publish/*/Microsoft.SourceLink.GitHub.resources.dll", "bin/Microsoft.SourceLink.Vsts.Git/net461/Microsoft.SourceLink.Vsts.Git.dll", - "bin/Microsoft.SourceLink.Vsts.Git/netcoreapp2.0/Microsoft.SourceLink.Vsts.Git.dll", + "bin/Microsoft.SourceLink.Vsts.Git/net461/*/Microsoft.SourceLink.Vsts.Git.resources.dll", + "bin/Microsoft.SourceLink.Vsts.Git/netcoreapp2.0/publish/Microsoft.SourceLink.Vsts.Git.dll", + "bin/Microsoft.SourceLink.Vsts.Git/netcoreapp2.0/publish/*/Microsoft.SourceLink.Vsts.Git.resources.dll", "bin/Microsoft.SourceLink.Vsts.Tfvc/net461/Microsoft.SourceLink.Vsts.Tfvc.dll", - "bin/Microsoft.SourceLink.Vsts.Tfvc/netcoreapp2.0/Microsoft.SourceLink.Vsts.Tfvc.dll" + "bin/Microsoft.SourceLink.Vsts.Tfvc/netcoreapp2.0/publish/Microsoft.SourceLink.Vsts.Tfvc.dll" ] }, { diff --git a/src/Microsoft.Build.Tasks.Git/GitOperations.cs b/src/Microsoft.Build.Tasks.Git.Operations/GitOperations.cs similarity index 87% rename from src/Microsoft.Build.Tasks.Git/GitOperations.cs rename to src/Microsoft.Build.Tasks.Git.Operations/GitOperations.cs index 6c182a97..1c4661c8 100644 --- a/src/Microsoft.Build.Tasks.Git/GitOperations.cs +++ b/src/Microsoft.Build.Tasks.Git.Operations/GitOperations.cs @@ -5,6 +5,8 @@ using System.Diagnostics; using System.IO; using System.Linq; +using System.Reflection; +using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using LibGit2Sharp; using Microsoft.Build.Framework; @@ -17,50 +19,6 @@ internal static class GitOperations { private const string SourceControlName = "git"; - static GitOperations() - { - // .NET Core apps that depend on native libraries load them directly from paths specified - // in .deps.json file of that app and the native library loader just works. - // However, .NET Core currently doesn't support .deps.json for plugins such as msbuild tasks. - if (IsRunningOnNetCore()) - { - var dir = Path.GetDirectoryName(typeof(GitOperations).Assembly.Location); - GlobalSettings.NativeLibraryPath = Path.Combine(dir, "runtimes", GetNativeLibraryRuntimeId(), "native"); - } - } - - /// - /// Returns true if the runtime is .NET Core. - /// - private static bool IsRunningOnNetCore() - => typeof(object).Assembly.GetName().Name != "mscorlib"; - - /// - /// Determines the RID to use when loading libgit2 native library. - /// This method only supports RIDs that are currently used by LibGit2Sharp.NativeBinaries. - /// - private static string GetNativeLibraryRuntimeId() - { - var processorArchitecture = IntPtr.Size == 8 ? "x64" : "x86"; - - if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) - { - return "win7-" + processorArchitecture; - } - - if (RuntimeInformation.IsOSPlatform(OSPlatform.OSX)) - { - return "osx"; - } - - if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux)) - { - return "linux-" + processorArchitecture; - } - - throw new PlatformNotSupportedException(); - } - public static string LocateRepository(string directory) { // Repository.Discover returns the path to .git directory for repositories with a working directory. @@ -69,7 +27,7 @@ public static string LocateRepository(string directory) return Repository.Discover(directory); } - public static string GetRepositoryUrl(this IRepository repository, string remoteName = null) + public static string GetRepositoryUrl(IRepository repository, string remoteName = null) { var remotes = repository.Network.Remotes; var remote = string.IsNullOrEmpty(remoteName) ? (remotes["origin"] ?? remotes.FirstOrDefault()) : remotes[remoteName]; @@ -153,7 +111,7 @@ private static bool TryParseScp(string value, out Uri uri) return Uri.TryCreate(url, UriKind.Absolute, out uri); } - public static string GetRevisionId(this IRepository repository) + public static string GetRevisionId(IRepository repository) { // An empty repository doesn't have a tip commit: return repository.Head.Tip?.Sha; @@ -178,7 +136,7 @@ private static bool SubmodulesSupported(IRepository repository, Func logWarning, Func fileExists) + public static ITaskItem[] GetSourceRoots(IRepository repository, Action logWarning, Func fileExists) { var result = new List(); var repoRoot = GetRepositoryRoot(repository); @@ -249,14 +207,14 @@ public static ITaskItem[] GetSourceRoots(this IRepository repository, Action repositoryFactory) diff --git a/src/Microsoft.Build.Tasks.Git.Operations/Microsoft.Build.Tasks.Git.Operations.csproj b/src/Microsoft.Build.Tasks.Git.Operations/Microsoft.Build.Tasks.Git.Operations.csproj new file mode 100644 index 00000000..5b8d5a09 --- /dev/null +++ b/src/Microsoft.Build.Tasks.Git.Operations/Microsoft.Build.Tasks.Git.Operations.csproj @@ -0,0 +1,26 @@ + + + netcoreapp2.0;net461 + + + true + Microsoft.Build.Tasks.Git + Microsoft.Build.Tasks.Git.nuspec + $(OutputPath) + + MSBuild tasks providing git repository information. + MSBuild Tasks source control git + true + + + + + + + + + + + + + diff --git a/src/Microsoft.Build.Tasks.Git/Microsoft.Build.Tasks.Git.nuspec b/src/Microsoft.Build.Tasks.Git.Operations/Microsoft.Build.Tasks.Git.nuspec similarity index 76% rename from src/Microsoft.Build.Tasks.Git/Microsoft.Build.Tasks.Git.nuspec rename to src/Microsoft.Build.Tasks.Git.Operations/Microsoft.Build.Tasks.Git.nuspec index 9c963555..cd77833f 100644 --- a/src/Microsoft.Build.Tasks.Git/Microsoft.Build.Tasks.Git.nuspec +++ b/src/Microsoft.Build.Tasks.Git.Operations/Microsoft.Build.Tasks.Git.nuspec @@ -22,18 +22,12 @@ - - - - - - - + + + + diff --git a/src/Microsoft.Build.Tasks.Git.Operations/RepositoryTasks.cs b/src/Microsoft.Build.Tasks.Git.Operations/RepositoryTasks.cs new file mode 100644 index 00000000..edf7d7a4 --- /dev/null +++ b/src/Microsoft.Build.Tasks.Git.Operations/RepositoryTasks.cs @@ -0,0 +1,84 @@ +// Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. + +using System; +using System.IO; +using LibGit2Sharp; + +namespace Microsoft.Build.Tasks.Git +{ + internal static class RepositoryTasks + { + private static bool Execute(T task, Action action) + where T: RepositoryTask + { + var log = task.Log; + + Repository repo; + try + { + repo = new Repository(task.LocalRepositoryId); + } + catch (RepositoryNotFoundException e) + { + log.LogErrorFromException(e); + return false; + } + + if (repo.Info.IsBare) + { + log.LogError(Resources.BareRepositoriesNotSupported, task.LocalRepositoryId); + return false; + } + + using (repo) + { + try + { + action(repo, task); + } + catch (LibGit2SharpException e) + { + log.LogErrorFromException(e); + } + } + + return !log.HasLoggedErrors; + } + + public static bool LocateRepository(LocateRepository task) + { + task.Id = GitOperations.LocateRepository(task.Directory); + + if (task.Id == null) + { + task.Log.LogError(Resources.UnableToLocateRepository, task.Directory); + } + + return !task.Log.HasLoggedErrors; + } + + public static bool GetRepositoryUrl(GetRepositoryUrl task) => + Execute(task, (repo, t) => + { + t.Url = GitOperations.GetRepositoryUrl(repo, t.RemoteName); + }); + + public static bool GetSourceRevisionId(GetSourceRevisionId task) => + Execute(task, (repo, t) => + { + t.RevisionId = GitOperations.GetRevisionId(repo); + }); + + public static bool GetSourceRoots(GetSourceRoots task) => + Execute(task, (repo, t) => + { + t.Roots = GitOperations.GetSourceRoots(repo, t.Log.LogWarning, File.Exists); + }); + + public static bool GetUntrackedFiles(GetUntrackedFiles task) => + Execute(task, (repo, t) => + { + t.UntrackedFiles = GitOperations.GetUntrackedFiles(repo, t.Files, t.ProjectDirectory, dir => new Repository(dir)); + }); + } +} diff --git a/src/Microsoft.Build.Tasks.Git/build/Microsoft.Build.Tasks.Git.props b/src/Microsoft.Build.Tasks.Git.Operations/build/Microsoft.Build.Tasks.Git.props similarity index 100% rename from src/Microsoft.Build.Tasks.Git/build/Microsoft.Build.Tasks.Git.props rename to src/Microsoft.Build.Tasks.Git.Operations/build/Microsoft.Build.Tasks.Git.props diff --git a/src/Microsoft.Build.Tasks.Git/build/Microsoft.Build.Tasks.Git.targets b/src/Microsoft.Build.Tasks.Git.Operations/build/Microsoft.Build.Tasks.Git.targets similarity index 100% rename from src/Microsoft.Build.Tasks.Git/build/Microsoft.Build.Tasks.Git.targets rename to src/Microsoft.Build.Tasks.Git.Operations/build/Microsoft.Build.Tasks.Git.targets diff --git a/src/Microsoft.Build.Tasks.Git.UnitTests/GitOperationsTests.cs b/src/Microsoft.Build.Tasks.Git.UnitTests/GitOperationsTests.cs index d0af1400..3d12c8ab 100644 --- a/src/Microsoft.Build.Tasks.Git.UnitTests/GitOperationsTests.cs +++ b/src/Microsoft.Build.Tasks.Git.UnitTests/GitOperationsTests.cs @@ -477,7 +477,7 @@ public void GetUntrackedFiles_ProjectInMainRepoIncludesFilesInSubmodules() { subRoot2, new TestRepository(subRoot2, commitSha: null, ignoredPaths: new[] { gitRoot + @"/sub/2/obj/b.cs" }) }, }; - var actual = repo.GetUntrackedFiles( + var actual = GitOperations.GetUntrackedFiles(repo, new[] { new MockItem(@"c.cs"), // not ignored @@ -523,7 +523,7 @@ public void GetUntrackedFiles_ProjectInSubmodule() { subRoot2, new TestRepository(subRoot2, commitSha: null, ignoredPaths: new[] { gitRoot + "/sub/2/obj/b.cs" }) }, }; - var actual = repo.GetUntrackedFiles( + var actual = GitOperations.GetUntrackedFiles(repo, new[] { new MockItem(@"c.cs"), // not ignored diff --git a/src/Microsoft.Build.Tasks.Git.UnitTests/Microsoft.Build.Tasks.Git.UnitTests.csproj b/src/Microsoft.Build.Tasks.Git.UnitTests/Microsoft.Build.Tasks.Git.UnitTests.csproj index c01a56cb..ffba1b5a 100644 --- a/src/Microsoft.Build.Tasks.Git.UnitTests/Microsoft.Build.Tasks.Git.UnitTests.csproj +++ b/src/Microsoft.Build.Tasks.Git.UnitTests/Microsoft.Build.Tasks.Git.UnitTests.csproj @@ -3,6 +3,7 @@ net461;netcoreapp2.0 + diff --git a/src/Microsoft.Build.Tasks.Git/GetRepositoryUrl.cs b/src/Microsoft.Build.Tasks.Git/GetRepositoryUrl.cs index 78092c0f..d8d4d780 100644 --- a/src/Microsoft.Build.Tasks.Git/GetRepositoryUrl.cs +++ b/src/Microsoft.Build.Tasks.Git/GetRepositoryUrl.cs @@ -1,6 +1,5 @@ // Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. -using LibGit2Sharp; using Microsoft.Build.Framework; namespace Microsoft.Build.Tasks.Git @@ -10,11 +9,8 @@ public sealed class GetRepositoryUrl : RepositoryTask public string RemoteName { get; set; } [Output] - public string Url { get; private set; } + public string Url { get; internal set; } - protected override void Execute(Repository repo) - { - Url = repo.GetRepositoryUrl(RemoteName); - } + public override bool Execute() => TaskImplementation.GetRepositoryUrl(this); } } diff --git a/src/Microsoft.Build.Tasks.Git/GetSourceRevisionId.cs b/src/Microsoft.Build.Tasks.Git/GetSourceRevisionId.cs index 9b32f4a8..d3fd8e0e 100644 --- a/src/Microsoft.Build.Tasks.Git/GetSourceRevisionId.cs +++ b/src/Microsoft.Build.Tasks.Git/GetSourceRevisionId.cs @@ -1,6 +1,5 @@ // Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. -using LibGit2Sharp; using Microsoft.Build.Framework; namespace Microsoft.Build.Tasks.Git @@ -8,11 +7,8 @@ namespace Microsoft.Build.Tasks.Git public sealed class GetSourceRevisionId : RepositoryTask { [Output] - public string RevisionId { get; private set; } + public string RevisionId { get; internal set; } - protected override void Execute(Repository repo) - { - RevisionId = repo.GetRevisionId(); - } + public override bool Execute() => TaskImplementation.GetSourceRevisionId(this); } } diff --git a/src/Microsoft.Build.Tasks.Git/GetSourceRoots.cs b/src/Microsoft.Build.Tasks.Git/GetSourceRoots.cs index aef05ba7..f81ef95e 100644 --- a/src/Microsoft.Build.Tasks.Git/GetSourceRoots.cs +++ b/src/Microsoft.Build.Tasks.Git/GetSourceRoots.cs @@ -1,8 +1,6 @@ // Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. -using LibGit2Sharp; using Microsoft.Build.Framework; -using System.IO; namespace Microsoft.Build.Tasks.Git { @@ -20,11 +18,8 @@ public sealed class GetSourceRoots : RepositoryTask /// NestedRoot: For a submodule root, a path of the submodule root relative to the repository root. Ends with a slash. /// [Output] - public ITaskItem[] Roots { get; private set; } + public ITaskItem[] Roots { get; internal set; } - protected override void Execute(Repository repo) - { - Roots = repo.GetSourceRoots(Log.LogWarning, File.Exists); - } + public override bool Execute() => TaskImplementation.GetSourceRoots(this); } } diff --git a/src/Microsoft.Build.Tasks.Git/GetUntrackedFiles.cs b/src/Microsoft.Build.Tasks.Git/GetUntrackedFiles.cs index 0064bab2..b4c81f09 100644 --- a/src/Microsoft.Build.Tasks.Git/GetUntrackedFiles.cs +++ b/src/Microsoft.Build.Tasks.Git/GetUntrackedFiles.cs @@ -1,6 +1,5 @@ // Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. -using LibGit2Sharp; using Microsoft.Build.Framework; namespace Microsoft.Build.Tasks.Git @@ -19,9 +18,6 @@ public sealed class GetUntrackedFiles : RepositoryTask [Output] public ITaskItem[] UntrackedFiles { get; set; } - protected override void Execute(Repository repo) - { - UntrackedFiles = repo.GetUntrackedFiles(Files, ProjectDirectory, dir => new Repository(dir)); - } + public override bool Execute() => TaskImplementation.GetUntrackedFiles(this); } } diff --git a/src/Microsoft.Build.Tasks.Git/GitLoaderContext.cs b/src/Microsoft.Build.Tasks.Git/GitLoaderContext.cs new file mode 100644 index 00000000..8ea2f3d4 --- /dev/null +++ b/src/Microsoft.Build.Tasks.Git/GitLoaderContext.cs @@ -0,0 +1,106 @@ +// Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. +#if !NET461 +using System; +using System.IO; +using System.Reflection; +using System.Runtime.InteropServices; +using System.Runtime.Loader; + +namespace Microsoft.Build.Tasks.Git +{ + internal sealed class GitLoaderContext : AssemblyLoadContext + { + public static readonly GitLoaderContext Instance = new GitLoaderContext(); + + protected override Assembly Load(AssemblyName assemblyName) + { + if (assemblyName.Name == "LibGit2Sharp") + { + var path = Path.Combine(Path.GetDirectoryName(typeof(TaskImplementation).Assembly.Location), assemblyName.Name + ".dll"); + return LoadFromAssemblyPath(path); + } + + return Default.LoadFromAssemblyName(assemblyName); + } + + protected override IntPtr LoadUnmanagedDll(string unmanagedDllName) + { + var modulePtr = IntPtr.Zero; + + if (unmanagedDllName.StartsWith("git2-", StringComparison.Ordinal) || + unmanagedDllName.StartsWith("libgit2-", StringComparison.Ordinal)) + { + var directory = GetNativeLibraryDirectory(); + var extension = GetNativeLibraryExtension(); + + if (!unmanagedDllName.EndsWith(extension, StringComparison.Ordinal)) + { + unmanagedDllName += extension; + } + + var nativeLibraryPath = Path.Combine(directory, unmanagedDllName); + if (!File.Exists(nativeLibraryPath)) + { + nativeLibraryPath = Path.Combine(directory, "lib" + unmanagedDllName); + } + + modulePtr = LoadUnmanagedDllFromPath(nativeLibraryPath); + } + + return (modulePtr != IntPtr.Zero) ? modulePtr : base.LoadUnmanagedDll(unmanagedDllName); + } + + internal static string GetNativeLibraryDirectory() + { + var dir = Path.GetDirectoryName(typeof(GitLoaderContext).Assembly.Location); + return Path.Combine(dir, "runtimes", GetNativeLibraryRuntimeId(), "native"); + } + + /// + /// Determines the RID to use when loading libgit2 native library. + /// This method only supports RIDs that are currently used by LibGit2Sharp.NativeBinaries. + /// + private static string GetNativeLibraryRuntimeId() + { + var processorArchitecture = IntPtr.Size == 8 ? "x64" : "x86"; + + if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) + { + return "win7-" + processorArchitecture; + } + + if (RuntimeInformation.IsOSPlatform(OSPlatform.OSX)) + { + return "osx"; + } + + if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux)) + { + return "linux-" + processorArchitecture; + } + + throw new PlatformNotSupportedException(); + } + + private static string GetNativeLibraryExtension() + { + if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) + { + return ".dll"; + } + + if (RuntimeInformation.IsOSPlatform(OSPlatform.OSX)) + { + return ".dylib"; + } + + if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux)) + { + return ".so"; + } + + throw new PlatformNotSupportedException(); + } + } +} +#endif \ No newline at end of file diff --git a/src/Microsoft.Build.Tasks.Git/LocateRepository.cs b/src/Microsoft.Build.Tasks.Git/LocateRepository.cs index 7abc2beb..40d761fc 100644 --- a/src/Microsoft.Build.Tasks.Git/LocateRepository.cs +++ b/src/Microsoft.Build.Tasks.Git/LocateRepository.cs @@ -14,16 +14,6 @@ public class LocateRepository : Task [Output] public string Id { get; set; } - public override bool Execute() - { - Id = GitOperations.LocateRepository(Directory); - - if (Id == null) - { - Log.LogError(Resources.UnableToLocateRepository, Directory); - } - - return !Log.HasLoggedErrors; - } + public override bool Execute() => TaskImplementation.LocateRepository(this); } } diff --git a/src/Microsoft.Build.Tasks.Git/Microsoft.Build.Tasks.Git.csproj b/src/Microsoft.Build.Tasks.Git/Microsoft.Build.Tasks.Git.csproj index 6fc6d606..43e3d6b3 100644 --- a/src/Microsoft.Build.Tasks.Git/Microsoft.Build.Tasks.Git.csproj +++ b/src/Microsoft.Build.Tasks.Git/Microsoft.Build.Tasks.Git.csproj @@ -1,15 +1,6 @@  netcoreapp2.0;net461 - - - true - $(MSBuildProjectName).nuspec - $(OutputPath) - - MSBuild tasks providing git repository information. - MSBuild Tasks source control git - true @@ -17,11 +8,11 @@ - + diff --git a/src/Microsoft.Build.Tasks.Git/RepositoryTask.cs b/src/Microsoft.Build.Tasks.Git/RepositoryTask.cs index 305ad1cc..87a787d5 100644 --- a/src/Microsoft.Build.Tasks.Git/RepositoryTask.cs +++ b/src/Microsoft.Build.Tasks.Git/RepositoryTask.cs @@ -1,6 +1,5 @@ // Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. -using LibGit2Sharp; using Microsoft.Build.Framework; using Microsoft.Build.Utilities; @@ -10,41 +9,5 @@ public abstract class RepositoryTask : Task { [Required] public string LocalRepositoryId { get; set; } - - protected abstract void Execute(Repository repo); - - public sealed override bool Execute() - { - Repository repo; - try - { - repo = new Repository(LocalRepositoryId); - } - catch (RepositoryNotFoundException e) - { - Log.LogErrorFromException(e); - return false; - } - - if (repo.Info.IsBare) - { - Log.LogError(Resources.BareRepositoriesNotSupported, LocalRepositoryId); - return false; - } - - using (repo) - { - try - { - Execute(repo); - } - catch (LibGit2SharpException e) - { - Log.LogErrorFromException(e); - } - } - - return !Log.HasLoggedErrors; - } } } diff --git a/src/Microsoft.Build.Tasks.Git/TaskImplementation.cs b/src/Microsoft.Build.Tasks.Git/TaskImplementation.cs new file mode 100644 index 00000000..b89cb9c6 --- /dev/null +++ b/src/Microsoft.Build.Tasks.Git/TaskImplementation.cs @@ -0,0 +1,36 @@ +// Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. + +using System; +using System.IO; +using System.Reflection; + +namespace Microsoft.Build.Tasks.Git +{ + internal static class TaskImplementation + { + public static Func LocateRepository; + public static Func GetRepositoryUrl; + public static Func GetSourceRevisionId; + public static Func GetSourceRoots; + public static Func GetUntrackedFiles; + + static TaskImplementation() + { +#if NET461 + var assemblyName = typeof(TaskImplementation).Assembly.GetName(); + assemblyName.Name = "Microsoft.Build.Tasks.Git.Operations"; + var assembly = Assembly.Load(assemblyName); +#else + var operationsPath = Path.Combine(Path.GetDirectoryName(typeof(TaskImplementation).Assembly.Location), "Microsoft.Build.Tasks.Git.Operations.dll"); + var assembly = GitLoaderContext.Instance.LoadFromAssemblyPath(operationsPath); +#endif + var type = assembly.GetType("Microsoft.Build.Tasks.Git.RepositoryTasks", throwOnError: true).GetTypeInfo(); + + LocateRepository = (Func)type.GetDeclaredMethod(nameof(LocateRepository)).CreateDelegate(typeof(Func)); + GetRepositoryUrl = (Func)type.GetDeclaredMethod(nameof(GetRepositoryUrl)).CreateDelegate(typeof(Func)); + GetSourceRevisionId = (Func)type.GetDeclaredMethod(nameof(GetSourceRevisionId)).CreateDelegate(typeof(Func)); + GetSourceRoots = (Func)type.GetDeclaredMethod(nameof(GetSourceRoots)).CreateDelegate(typeof(Func)); + GetUntrackedFiles = (Func)type.GetDeclaredMethod(nameof(GetUntrackedFiles)).CreateDelegate(typeof(Func)); + } + } +} diff --git a/src/SourceLink.Common/Microsoft.SourceLink.Common.nuspec b/src/SourceLink.Common/Microsoft.SourceLink.Common.nuspec index 5084919d..6b24b3db 100644 --- a/src/SourceLink.Common/Microsoft.SourceLink.Common.nuspec +++ b/src/SourceLink.Common/Microsoft.SourceLink.Common.nuspec @@ -14,8 +14,10 @@ $Serviceable$ - + + + diff --git a/src/SourceLink.GitHub/Microsoft.SourceLink.GitHub.nuspec b/src/SourceLink.GitHub/Microsoft.SourceLink.GitHub.nuspec index bc91a41c..52ef20da 100644 --- a/src/SourceLink.GitHub/Microsoft.SourceLink.GitHub.nuspec +++ b/src/SourceLink.GitHub/Microsoft.SourceLink.GitHub.nuspec @@ -19,8 +19,8 @@ - - + + diff --git a/src/SourceLink.Vsts.Git/Microsoft.SourceLink.Vsts.Git.nuspec b/src/SourceLink.Vsts.Git/Microsoft.SourceLink.Vsts.Git.nuspec index 503a0dbc..95b94783 100644 --- a/src/SourceLink.Vsts.Git/Microsoft.SourceLink.Vsts.Git.nuspec +++ b/src/SourceLink.Vsts.Git/Microsoft.SourceLink.Vsts.Git.nuspec @@ -19,8 +19,8 @@ - - + + diff --git a/src/SourceLink.Vsts.Tfvc/Microsoft.SourceLink.Vsts.Tfvc.nuspec b/src/SourceLink.Vsts.Tfvc/Microsoft.SourceLink.Vsts.Tfvc.nuspec index 57a09d7e..eb714766 100644 --- a/src/SourceLink.Vsts.Tfvc/Microsoft.SourceLink.Vsts.Tfvc.nuspec +++ b/src/SourceLink.Vsts.Tfvc/Microsoft.SourceLink.Vsts.Tfvc.nuspec @@ -19,8 +19,8 @@ - - + +