diff --git a/Readme.md b/Readme.md index 9034dd3b55..d4c5cb508a 100644 --- a/Readme.md +++ b/Readme.md @@ -152,12 +152,6 @@ Note that Scalar on Mac is under active development. git clone https://github.com/microsoft/scalar.git src ``` -* Using XCode, open `Scalar/ReadObjectHook/Scalar.ReadObjectHook.Mac.xcodeproj`. - - * Select the `Scalar.ReadObjectHook.Mac` project. - * Under "Signing", select your developer certificate, which may be an organization - certificate. - * Run the build and installation scripts: ``` diff --git a/Scalar.Build/Scalar.props b/Scalar.Build/Scalar.props index c952cd7ed6..112847f365 100644 --- a/Scalar.Build/Scalar.props +++ b/Scalar.Build/Scalar.props @@ -3,7 +3,7 @@ 0.2.173.2 - 2.20191002.1-sc + 2.20191003.3-sc diff --git a/Scalar.Common/FileSystem/HooksInstaller.cs b/Scalar.Common/FileSystem/HooksInstaller.cs deleted file mode 100644 index 56a0f82a7a..0000000000 --- a/Scalar.Common/FileSystem/HooksInstaller.cs +++ /dev/null @@ -1,199 +0,0 @@ -using Scalar.Common.Git; -using Scalar.Common.Tracing; -using System; -using System.Collections.Generic; -using System.Diagnostics; -using System.IO; -using System.Linq; -using System.Reflection; -using System.Threading; - -namespace Scalar.Common.FileSystem -{ - public static class HooksInstaller - { - private static readonly string ExecutingDirectory; - private static readonly HookData[] NativeHooks = new[] - { - new HookData(ScalarConstants.DotGit.Hooks.ReadObjectName, ScalarConstants.DotGit.Hooks.ReadObjectPath, ScalarPlatform.Instance.Constants.ScalarReadObjectHookExecutableName), - }; - - static HooksInstaller() - { - ExecutingDirectory = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location); - } - - public static bool InstallHooks(ScalarContext context, out string error) - { - error = string.Empty; - try - { - foreach (HookData hook in NativeHooks) - { - string installedHookPath = Path.Combine(ExecutingDirectory, hook.ExecutableName); - string targetHookPath = Path.Combine(context.Enlistment.WorkingDirectoryBackingRoot, hook.Path + ScalarPlatform.Instance.Constants.ExecutableExtension); - if (!TryHooksInstallationAction(() => CopyHook(context, installedHookPath, targetHookPath), out error)) - { - error = "Failed to copy " + installedHookPath + "\n" + error; - return false; - } - } - } - catch (Exception e) - { - error = e.ToString(); - return false; - } - - return true; - } - - public static bool TryUpdateHooks(ScalarContext context, out string errorMessage) - { - errorMessage = string.Empty; - foreach (HookData hook in NativeHooks) - { - if (!TryUpdateHook(context, hook, out errorMessage)) - { - return false; - } - } - - return true; - } - - public static void CopyHook(ScalarContext context, string sourcePath, string destinationPath) - { - Exception ex; - if (!context.FileSystem.TryCopyToTempFileAndRename(sourcePath, destinationPath, out ex)) - { - throw new RetryableException($"Error installing {sourcePath} to {destinationPath}", ex); - } - } - - /// - /// Try to perform the specified action. The action will be retried (with backoff) up to 3 times. - /// - /// Action to perform - /// Error message - /// True if the action succeeded and false otherwise - /// This method is optimized for the hooks installation process and should not be used - /// as a generic retry mechanism. See RetryWrapper for a general purpose retry mechanism - public static bool TryHooksInstallationAction(Action action, out string errorMessage) - { - int retriesLeft = 3; - int retryWaitMillis = 500; // Will grow exponentially on each retry attempt - errorMessage = null; - - while (true) - { - try - { - action(); - return true; - } - catch (RetryableException re) - { - if (retriesLeft == 0) - { - errorMessage = re.InnerException.ToString(); - return false; - } - - Thread.Sleep(retryWaitMillis); - retriesLeft -= 1; - retryWaitMillis *= 2; - } - catch (Exception e) - { - errorMessage = e.ToString(); - return false; - } - } - } - - private static bool TryUpdateHook( - ScalarContext context, - HookData hook, - out string errorMessage) - { - bool copyHook = false; - string enlistmentHookPath = Path.Combine(context.Enlistment.WorkingDirectoryBackingRoot, hook.Path + ScalarPlatform.Instance.Constants.ExecutableExtension); - string installedHookPath = Path.Combine(ExecutingDirectory, hook.ExecutableName); - - if (!context.FileSystem.FileExists(installedHookPath)) - { - errorMessage = hook.ExecutableName + " cannot be found at " + installedHookPath; - return false; - } - - if (!context.FileSystem.FileExists(enlistmentHookPath)) - { - copyHook = true; - - EventMetadata metadata = new EventMetadata(); - metadata.Add("Area", "Mount"); - metadata.Add(nameof(enlistmentHookPath), enlistmentHookPath); - metadata.Add(nameof(installedHookPath), installedHookPath); - metadata.Add(TracingConstants.MessageKey.WarningMessage, hook.Name + " not found in enlistment, copying from installation folder"); - context.Tracer.RelatedWarning(hook.Name + " MissingFromEnlistment", metadata); - } - else - { - try - { - FileVersionInfo enlistmentVersion = FileVersionInfo.GetVersionInfo(enlistmentHookPath); - FileVersionInfo installedVersion = FileVersionInfo.GetVersionInfo(installedHookPath); - copyHook = enlistmentVersion.FileVersion != installedVersion.FileVersion; - } - catch (Exception e) - { - EventMetadata metadata = new EventMetadata(); - metadata.Add("Area", "Mount"); - metadata.Add(nameof(enlistmentHookPath), enlistmentHookPath); - metadata.Add(nameof(installedHookPath), installedHookPath); - metadata.Add("Exception", e.ToString()); - context.Tracer.RelatedError(metadata, "Failed to compare " + hook.Name + " version"); - errorMessage = "Error comparing " + hook.Name + " versions. " + ConsoleHelper.GetScalarLogMessage(context.Enlistment.EnlistmentRoot); - return false; - } - } - - if (copyHook) - { - try - { - CopyHook(context, installedHookPath, enlistmentHookPath); - } - catch (Exception e) - { - EventMetadata metadata = new EventMetadata(); - metadata.Add("Area", "Mount"); - metadata.Add(nameof(enlistmentHookPath), enlistmentHookPath); - metadata.Add(nameof(installedHookPath), installedHookPath); - metadata.Add("Exception", e.ToString()); - context.Tracer.RelatedError(metadata, "Failed to copy " + hook.Name + " to enlistment"); - errorMessage = "Error copying " + hook.Name + " to enlistment. " + ConsoleHelper.GetScalarLogMessage(context.Enlistment.EnlistmentRoot); - return false; - } - } - - errorMessage = null; - return true; - } - - private class HookData - { - public HookData(string name, string path, string executableName) - { - this.Name = name; - this.Path = path; - this.ExecutableName = executableName; - } - - public string Name { get; } - public string Path { get; } - public string ExecutableName { get; } - } - } -} diff --git a/Scalar.Common/Git/GitConfigSetting.cs b/Scalar.Common/Git/GitConfigSetting.cs index 1200ae040e..86cd64de04 100644 --- a/Scalar.Common/Git/GitConfigSetting.cs +++ b/Scalar.Common/Git/GitConfigSetting.cs @@ -4,7 +4,6 @@ namespace Scalar.Common.Git { public class GitConfigSetting { - public const string CoreVirtualizeObjectsName = "core.virtualizeobjects"; public const string CredentialUseHttpPath = "credential.\"https://dev.azure.com\".useHttpPath"; public const string HttpSslCert = "http.sslcert"; diff --git a/Scalar.Common/Git/GitProcess.cs b/Scalar.Common/Git/GitProcess.cs index 51defa9061..6df995f389 100644 --- a/Scalar.Common/Git/GitProcess.cs +++ b/Scalar.Common/Git/GitProcess.cs @@ -90,7 +90,7 @@ public static Result Init(Enlistment enlistment) public static Result SparseCheckoutInit(Enlistment enlistment) { - return new GitProcess(enlistment).InvokeGitInWorkingDirectoryRoot("sparse-checkout init --cone", useReadObjectHook: false); + return new GitProcess(enlistment).InvokeGitInWorkingDirectoryRoot("sparse-checkout init --cone", fetchMissingObjects: false); } public static ConfigResult GetFromGlobalConfig(string gitBinPath, string settingName) @@ -413,19 +413,19 @@ public Result CreateBranchWithUpstream(string branchToCreate, string upstreamBra public Result ForceCheckout(string target) { - return this.InvokeGitInWorkingDirectoryRoot("checkout -f " + target, useReadObjectHook: true); + return this.InvokeGitInWorkingDirectoryRoot("checkout -f " + target, fetchMissingObjects: true); } public Result ForceCheckoutAllFiles() { - return this.InvokeGitInWorkingDirectoryRoot("checkout HEAD -- .", useReadObjectHook: true); + return this.InvokeGitInWorkingDirectoryRoot("checkout HEAD -- .", fetchMissingObjects: true); } public Result SparseCheckoutSet(List foldersToSet) { return this.InvokeGitInWorkingDirectoryRoot( $"sparse-checkout set --stdin", - useReadObjectHook: true, + fetchMissingObjects: true, writeStdIn: writer => { foreach (string path in foldersToSet) @@ -449,7 +449,7 @@ public Result Status(bool allowObjectDownloads, bool useStatusCache, bool showUn command += " -uall"; } - return this.InvokeGitInWorkingDirectoryRoot(command, useReadObjectHook: allowObjectDownloads); + return this.InvokeGitInWorkingDirectoryRoot(command, fetchMissingObjects: allowObjectDownloads); } public Result UnpackObjects(Stream packFileStream) @@ -490,7 +490,7 @@ public Result WriteCommitGraph(string objectDir, List packs) string command = "commit-graph write --stdin-packs --split --size-multiple=4 --object-dir \"" + objectDir + "\""; return this.InvokeGitInWorkingDirectoryRoot( command, - useReadObjectHook: true, + fetchMissingObjects: true, writeStdIn: writer => { foreach (string packIndex in packs) @@ -506,7 +506,7 @@ public Result WriteCommitGraph(string objectDir, List packs) public Result VerifyCommitGraph(string objectDir) { string command = "commit-graph verify --shallow --object-dir \"" + objectDir + "\""; - return this.InvokeGitInWorkingDirectoryRoot(command, useReadObjectHook: true); + return this.InvokeGitInWorkingDirectoryRoot(command, fetchMissingObjects: true); } public Result IndexPack(string packfilePath, string idxOutputPath) @@ -547,7 +547,7 @@ public Result LsFiles(Action parseStdOutLine) { return this.InvokeGitInWorkingDirectoryRoot( "ls-files -v", - useReadObjectHook: false, + fetchMissingObjects: false, parseStdOutLine: parseStdOutLine); } @@ -588,7 +588,7 @@ public Result MultiPackIndexRepack(string gitObjectDirectory, string batchSize) return this.InvokeGitAgainstDotGitFolder($"-c pack.threads=1 multi-pack-index repack --object-dir=\"{gitObjectDirectory}\" --batch-size={batchSize}"); } - public Process GetGitProcess(string command, string workingDirectory, string dotGitDirectory, bool useReadObjectHook, bool redirectStandardError, string gitObjectsDirectory) + public Process GetGitProcess(string command, string workingDirectory, string dotGitDirectory, bool fetchMissingObjects, bool redirectStandardError, string gitObjectsDirectory) { ProcessStartInfo processInfo = new ProcessStartInfo(this.gitBinPath); processInfo.WorkingDirectory = workingDirectory; @@ -632,9 +632,9 @@ public Process GetGitProcess(string command, string workingDirectory, string dot processInfo.EnvironmentVariables["GIT_OBJECT_DIRECTORY"] = gitObjectsDirectory; } - if (!useReadObjectHook) + if (!fetchMissingObjects) { - command = "-c " + GitConfigSetting.CoreVirtualizeObjectsName + "=false " + command; + command = $"-c {ScalarConstants.GitConfig.UseGvfsHelper}=false {command}"; } if (!string.IsNullOrEmpty(dotGitDirectory)) @@ -654,7 +654,7 @@ protected virtual Result InvokeGitImpl( string command, string workingDirectory, string dotGitDirectory, - bool useReadObjectHook, + bool fetchMissingObjects, Action writeStdIn, Action parseStdOutLine, int timeoutMs, @@ -670,7 +670,13 @@ protected virtual Result InvokeGitImpl( // From https://msdn.microsoft.com/en-us/library/system.diagnostics.process.standardoutput.aspx // To avoid deadlocks, use asynchronous read operations on at least one of the streams. // Do not perform a synchronous read to the end of both redirected streams. - using (this.executingProcess = this.GetGitProcess(command, workingDirectory, dotGitDirectory, useReadObjectHook, redirectStandardError: true, gitObjectsDirectory: gitObjectsDirectory)) + using (this.executingProcess = this.GetGitProcess( + command, + workingDirectory, + dotGitDirectory, + fetchMissingObjects: fetchMissingObjects, + redirectStandardError: true, + gitObjectsDirectory: gitObjectsDirectory)) { StringBuilder output = new StringBuilder(); StringBuilder errors = new StringBuilder(); @@ -793,7 +799,7 @@ private Result InvokeGitOutsideEnlistment( command, workingDirectory: Environment.SystemDirectory, dotGitDirectory: null, - useReadObjectHook: false, + fetchMissingObjects: false, writeStdIn: writeStdIn, parseStdOutLine: parseStdOutLine, timeoutMs: timeout); @@ -804,7 +810,7 @@ private Result InvokeGitOutsideEnlistment( /// private Result InvokeGitInWorkingDirectoryRoot( string command, - bool useReadObjectHook, + bool fetchMissingObjects, Action writeStdIn = null, Action parseStdOutLine = null) { @@ -812,7 +818,7 @@ private Result InvokeGitInWorkingDirectoryRoot( command, workingDirectory: this.workingDirectoryRoot, dotGitDirectory: null, - useReadObjectHook: useReadObjectHook, + fetchMissingObjects: fetchMissingObjects, writeStdIn: writeStdIn, parseStdOutLine: parseStdOutLine, timeoutMs: -1); @@ -840,7 +846,7 @@ private Result InvokeGitAgainstDotGitFolder( command, workingDirectory: Environment.SystemDirectory, dotGitDirectory: this.dotGitRoot, - useReadObjectHook: false, + fetchMissingObjects: false, writeStdIn: writeStdIn, parseStdOutLine: parseStdOutLine, timeoutMs: -1, diff --git a/Scalar.Common/Prefetch/BlobPrefetcher.cs b/Scalar.Common/Prefetch/BlobPrefetcher.cs deleted file mode 100644 index d929516cc2..0000000000 --- a/Scalar.Common/Prefetch/BlobPrefetcher.cs +++ /dev/null @@ -1,548 +0,0 @@ -using Newtonsoft.Json; -using Scalar.Common.FileSystem; -using Scalar.Common.Git; -using Scalar.Common.Http; -using Scalar.Common.Prefetch.Git; -using Scalar.Common.Prefetch.Pipeline; -using Scalar.Common.Tracing; -using System; -using System.Collections.Concurrent; -using System.Collections.Generic; -using System.IO; -using System.Linq; -using System.Threading; - -namespace Scalar.Common.Prefetch -{ - public class BlobPrefetcher - { - protected const string RefsHeadsGitPath = "refs/heads/"; - - protected readonly Enlistment Enlistment; - protected readonly GitObjectsHttpRequestor ObjectRequestor; - protected readonly GitObjects GitObjects; - protected readonly ITracer Tracer; - - protected readonly int ChunkSize; - protected readonly int SearchThreadCount; - protected readonly int DownloadThreadCount; - protected readonly int IndexThreadCount; - - protected readonly bool SkipConfigUpdate; - - private const string AreaPath = nameof(BlobPrefetcher); - private static string pathSeparatorString = Path.DirectorySeparatorChar.ToString(); - - private FileBasedDictionary lastPrefetchArgs; - - public BlobPrefetcher( - ITracer tracer, - Enlistment enlistment, - GitObjectsHttpRequestor objectRequestor, - List fileList, - List folderList, - FileBasedDictionary lastPrefetchArgs, - int chunkSize, - int searchThreadCount, - int downloadThreadCount, - int indexThreadCount) - { - this.SearchThreadCount = searchThreadCount; - this.DownloadThreadCount = downloadThreadCount; - this.IndexThreadCount = indexThreadCount; - this.ChunkSize = chunkSize; - this.Tracer = tracer; - this.Enlistment = enlistment; - this.ObjectRequestor = objectRequestor; - - this.GitObjects = new PrefetchGitObjects(tracer, enlistment, this.ObjectRequestor); - this.FileList = fileList ?? new List(); - this.FolderList = folderList ?? new List(); - - this.lastPrefetchArgs = lastPrefetchArgs; - - // We never want to update config settings for a ScalarEnlistment - this.SkipConfigUpdate = enlistment is ScalarEnlistment; - } - - public bool HasFailures { get; protected set; } - - public List FileList { get; } - - public List FolderList { get; } - - public static bool TryLoadFolderList(Enlistment enlistment, string foldersInput, string folderListFile, List folderListOutput, bool readListFromStdIn, out string error) - { - return TryLoadFileOrFolderList( - enlistment, - foldersInput, - folderListFile, - isFolder: true, - readListFromStdIn: readListFromStdIn, - output: folderListOutput, - elementValidationFunction: s => - s.Contains("*") ? - "Wildcards are not supported for folders. Invalid entry: " + s : - null, - error: out error); - } - - public static bool TryLoadFileList(Enlistment enlistment, string filesInput, string filesListFile, List fileListOutput, bool readListFromStdIn, out string error) - { - return TryLoadFileOrFolderList( - enlistment, - filesInput, - filesListFile, - readListFromStdIn: readListFromStdIn, - isFolder: false, - output: fileListOutput, - elementValidationFunction: s => - { - if (s.IndexOf('*', 1) != -1) - { - return "Only prefix wildcards are supported. Invalid entry: " + s; - } - - if (s.EndsWith(ScalarConstants.GitPathSeparatorString) || - s.EndsWith(pathSeparatorString)) - { - return "Folders are not allowed in the file list. Invalid entry: " + s; - } - - return null; - }, - error: out error); - } - - public static bool IsNoopPrefetch( - ITracer tracer, - FileBasedDictionary lastPrefetchArgs, - string commitId, - List files, - List folders) - { - if (lastPrefetchArgs != null && - lastPrefetchArgs.TryGetValue(PrefetchArgs.CommitId, out string lastCommitId) && - lastPrefetchArgs.TryGetValue(PrefetchArgs.Files, out string lastFilesString) && - lastPrefetchArgs.TryGetValue(PrefetchArgs.Folders, out string lastFoldersString)) - { - string newFilesString = JsonConvert.SerializeObject(files); - string newFoldersString = JsonConvert.SerializeObject(folders); - bool isNoop = - commitId == lastCommitId && - newFilesString == lastFilesString && - newFoldersString == lastFoldersString; - - tracer.RelatedEvent( - EventLevel.Informational, - "BlobPrefetcher.IsNoopPrefetch", - new EventMetadata - { - { "Last" + PrefetchArgs.CommitId, lastCommitId }, - { "Last" + PrefetchArgs.Files, lastFilesString }, - { "Last" + PrefetchArgs.Folders, lastFoldersString }, - { "New" + PrefetchArgs.CommitId, commitId }, - { "New" + PrefetchArgs.Files, newFilesString }, - { "New" + PrefetchArgs.Folders, newFoldersString }, - { "Result", isNoop }, - }); - - return isNoop; - } - - return false; - } - - public static void AppendToNewlineSeparatedFile(string filename, string newContent) - { - AppendToNewlineSeparatedFile(new PhysicalFileSystem(), filename, newContent); - } - - public static void AppendToNewlineSeparatedFile(PhysicalFileSystem fileSystem, string filename, string newContent) - { - using (Stream fileStream = fileSystem.OpenFileStream(filename, FileMode.OpenOrCreate, FileAccess.ReadWrite, FileShare.ReadWrite, false)) - { - using (StreamReader reader = new StreamReader(fileStream)) - using (StreamWriter writer = new StreamWriter(fileStream)) - { - long position = reader.BaseStream.Seek(0, SeekOrigin.End); - if (position > 0) - { - reader.BaseStream.Seek(position - 1, SeekOrigin.Begin); - } - - string lastCharacter = reader.ReadToEnd(); - if (lastCharacter != "\n" && lastCharacter != string.Empty) - { - writer.Write("\n"); - } - - writer.Write(newContent.Trim()); - writer.Write("\n"); - } - - fileStream.Close(); - } - } - - public void PrefetchWithStats( - string branchOrCommit, - bool isBranch, - out int matchedBlobCount, - out int downloadedBlobCount) - { - matchedBlobCount = 0; - downloadedBlobCount = 0; - - if (string.IsNullOrWhiteSpace(branchOrCommit)) - { - throw new FetchException("Must specify branch or commit to fetch"); - } - - GitRefs refs = null; - string commitToFetch; - if (isBranch) - { - refs = this.ObjectRequestor.QueryInfoRefs(branchOrCommit); - if (refs == null) - { - throw new FetchException("Could not query info/refs from: {0}", this.Enlistment.RepoUrl); - } - else if (refs.Count == 0) - { - throw new FetchException("Could not find branch {0} in info/refs from: {1}", branchOrCommit, this.Enlistment.RepoUrl); - } - - commitToFetch = refs.GetTipCommitId(branchOrCommit); - } - else - { - commitToFetch = branchOrCommit; - } - - this.DownloadMissingCommit(commitToFetch, this.GitObjects); - - // For FastFetch only, examine the shallow file to determine the previous commit that had been fetched - string shallowFile = Path.Combine(this.Enlistment.WorkingDirectoryBackingRoot, ScalarConstants.DotGit.Shallow); - string previousCommit = null; - - // Use the shallow file to find a recent commit to diff against to try and reduce the number of SHAs to check. - if (File.Exists(shallowFile)) - { - previousCommit = File.ReadAllLines(shallowFile).Where(line => !string.IsNullOrWhiteSpace(line)).LastOrDefault(); - if (string.IsNullOrWhiteSpace(previousCommit)) - { - this.Tracer.RelatedError("Shallow file exists, but contains no valid SHAs."); - this.HasFailures = true; - return; - } - } - - BlockingCollection availableBlobs = new BlockingCollection(); - - //// - // First create the pipeline - // - // diff ---> blobFinder ---> downloader ---> packIndexer - - // diff - // Inputs: - // * files/folders - // * commit id - // Outputs: - // * RequiredBlobs (property): Blob ids required to satisfy desired paths - // * FileAddOperations (property): Repo-relative paths corresponding to those blob ids - DiffHelper diff = new DiffHelper(this.Tracer, this.Enlistment, this.FileList, this.FolderList, includeSymLinks: false); - - // blobFinder - // Inputs: - // * requiredBlobs (in param): Blob ids from output of `diff` - // Outputs: - // * availableBlobs (out param): Locally available blob ids (shared between `blobFinder`, `downloader`, and `packIndexer`, all add blob ids to the list as they are locally available) - // * MissingBlobs (property): Blob ids that are missing and need to be downloaded - // * AvailableBlobs (property): Same as availableBlobs - FindBlobsStage blobFinder = new FindBlobsStage(this.SearchThreadCount, diff.RequiredBlobs, availableBlobs, this.Tracer, this.Enlistment); - - // downloader - // Inputs: - // * missingBlobs (in param): Blob ids from output of `blobFinder` - // Outputs: - // * availableBlobs (out param): Loose objects that have completed downloading (shared between `blobFinder`, `downloader`, and `packIndexer`, all add blob ids to the list as they are locally available) - // * AvailableObjects (property): Same as availableBlobs - // * AvailablePacks (property): Packfiles that have completed downloading - BatchObjectDownloadStage downloader = new BatchObjectDownloadStage(this.DownloadThreadCount, this.ChunkSize, blobFinder.MissingBlobs, availableBlobs, this.Tracer, this.Enlistment, this.ObjectRequestor, this.GitObjects); - - // packIndexer - // Inputs: - // * availablePacks (in param): Packfiles that have completed downloading from output of `downloader` - // Outputs: - // * availableBlobs (out param): Blobs that have completed downloading and indexing (shared between `blobFinder`, `downloader`, and `packIndexer`, all add blob ids to the list as they are locally available) - IndexPackStage packIndexer = new IndexPackStage(this.IndexThreadCount, downloader.AvailablePacks, availableBlobs, this.Tracer, this.GitObjects); - - // All the stages of the pipeline are created and wired up, now kick them off in the proper sequence - - ThreadStart performDiff = () => - { - diff.PerformDiff(previousCommit, commitToFetch); - this.HasFailures |= diff.HasFailures; - }; - - new Thread(performDiff).Start(); - - blobFinder.Start(); - downloader.Start(); - - // If indexing happens during searching, searching progressively gets slower, so wait on searching before indexing. - blobFinder.WaitForCompletion(); - this.HasFailures |= blobFinder.HasFailures; - - packIndexer.Start(); - - downloader.WaitForCompletion(); - this.HasFailures |= downloader.HasFailures; - - packIndexer.WaitForCompletion(); - this.HasFailures |= packIndexer.HasFailures; - - availableBlobs.CompleteAdding(); - - matchedBlobCount = blobFinder.AvailableBlobCount + blobFinder.MissingBlobCount; - downloadedBlobCount = blobFinder.MissingBlobCount; - - if (!this.SkipConfigUpdate && !this.HasFailures) - { - this.UpdateRefs(branchOrCommit, isBranch, refs); - - if (isBranch) - { - this.HasFailures |= !this.UpdateRefSpec(this.Tracer, this.Enlistment, branchOrCommit, refs); - } - } - - if (!this.HasFailures) - { - this.SavePrefetchArgs(commitToFetch); - } - } - - protected bool UpdateRefSpec(ITracer tracer, Enlistment enlistment, string branchOrCommit, GitRefs refs) - { - using (ITracer activity = tracer.StartActivity("UpdateRefSpec", EventLevel.Informational, Keywords.Telemetry, metadata: null)) - { - const string OriginRefMapSettingName = "remote.origin.fetch"; - - // We must update the refspec to get proper "git pull" functionality. - string localBranch = branchOrCommit.StartsWith(RefsHeadsGitPath) ? branchOrCommit : (RefsHeadsGitPath + branchOrCommit); - string remoteBranch = refs.GetBranchRefPairs().Single().Key; - string refSpec = "+" + localBranch + ":" + remoteBranch; - - GitProcess git = new GitProcess(enlistment); - - // Replace all ref-specs this - // * ensures the default refspec (remote.origin.fetch=+refs/heads/*:refs/remotes/origin/*) is removed which avoids some "git fetch/pull" failures - // * gives added "git fetch" performance since git will only fetch the branch provided in the refspec. - GitProcess.Result setResult = git.SetInLocalConfig(OriginRefMapSettingName, refSpec, replaceAll: true); - if (setResult.ExitCodeIsFailure) - { - activity.RelatedError("Could not update ref spec to {0}: {1}", refSpec, setResult.Errors); - return false; - } - } - - return true; - } - - /// - /// * Updates any remote branch (N/A for fetch of detached commit) - /// * Updates shallow file - /// - protected virtual void UpdateRefs(string branchOrCommit, bool isBranch, GitRefs refs) - { - string commitSha = null; - if (isBranch) - { - KeyValuePair remoteRef = refs.GetBranchRefPairs().Single(); - string remoteBranch = remoteRef.Key; - commitSha = remoteRef.Value; - - this.HasFailures |= !this.UpdateRef(this.Tracer, remoteBranch, commitSha); - } - else - { - commitSha = branchOrCommit; - } - - // Update shallow file to ensure this is a valid shallow repo - AppendToNewlineSeparatedFile(Path.Combine(this.Enlistment.WorkingDirectoryBackingRoot, ScalarConstants.DotGit.Shallow), commitSha); - } - - protected bool UpdateRef(ITracer tracer, string refName, string targetCommitish) - { - EventMetadata metadata = new EventMetadata(); - metadata.Add("RefName", refName); - metadata.Add("TargetCommitish", targetCommitish); - using (ITracer activity = tracer.StartActivity(AreaPath, EventLevel.Informational, Keywords.Telemetry, metadata)) - { - GitProcess gitProcess = new GitProcess(this.Enlistment); - GitProcess.Result result = null; - if (this.IsSymbolicRef(targetCommitish)) - { - // Using update-ref with a branch name will leave a SHA in the ref file which detaches HEAD, so use symbolic-ref instead. - result = gitProcess.UpdateBranchSymbolicRef(refName, targetCommitish); - } - else - { - result = gitProcess.UpdateBranchSha(refName, targetCommitish); - } - - if (result.ExitCodeIsFailure) - { - activity.RelatedError(result.Errors); - return false; - } - - return true; - } - } - - protected void DownloadMissingCommit(string commitSha, GitObjects gitObjects) - { - EventMetadata startMetadata = new EventMetadata(); - startMetadata.Add("CommitSha", commitSha); - - using (ITracer activity = this.Tracer.StartActivity("DownloadTrees", EventLevel.Informational, Keywords.Telemetry, startMetadata)) - { - using (LibGit2Repo repo = new LibGit2Repo(this.Tracer, this.Enlistment.WorkingDirectoryBackingRoot)) - { - if (!repo.ObjectExists(commitSha)) - { - if (!gitObjects.TryDownloadCommit(commitSha)) - { - EventMetadata metadata = new EventMetadata(); - metadata.Add("ObjectsEndpointUrl", this.ObjectRequestor.CacheServer.ObjectsEndpointUrl); - activity.RelatedError(metadata, "Could not download commits"); - throw new FetchException("Could not download commits from {0}", this.ObjectRequestor.CacheServer.ObjectsEndpointUrl); - } - } - } - } - } - - private static IEnumerable GetFilesFromVerbParameter(string valueString) - { - return valueString.Split(new[] { ';' }, StringSplitOptions.RemoveEmptyEntries); - } - - private static IEnumerable GetFilesFromFile(string fileName, out string error) - { - error = null; - if (string.IsNullOrWhiteSpace(fileName)) - { - return Enumerable.Empty(); - } - - if (!File.Exists(fileName)) - { - error = string.Format("Could not find '{0}' list file.", fileName); - return Enumerable.Empty(); - } - - return File.ReadAllLines(fileName) - .Select(line => line.Trim()); - } - - private static IEnumerable GetFilesFromStdin(bool shouldRead) - { - if (!shouldRead) - { - yield break; - } - - string line; - while ((line = Console.In.ReadLine()) != null) - { - yield return line.Trim(); - } - } - - private static bool TryLoadFileOrFolderList(Enlistment enlistment, string valueString, string listFileName, bool readListFromStdIn, bool isFolder, List output, Func elementValidationFunction, out string error) - { - output.AddRange( - GetFilesFromVerbParameter(valueString) - .Union(GetFilesFromFile(listFileName, out string fileReadError)) - .Union(GetFilesFromStdin(readListFromStdIn)) - .Where(path => !path.StartsWith(ScalarConstants.GitCommentSign.ToString())) - .Where(path => !string.IsNullOrWhiteSpace(path)) - .Select(path => BlobPrefetcher.ToFilterPath(path, isFolder: isFolder))); - - if (!string.IsNullOrWhiteSpace(fileReadError)) - { - error = fileReadError; - return false; - } - - string[] errorArray = output - .Select(elementValidationFunction) - .Where(s => !string.IsNullOrWhiteSpace(s)) - .ToArray(); - - if (errorArray != null && errorArray.Length > 0) - { - error = string.Join("\n", errorArray); - return false; - } - - error = null; - return true; - } - - private static string ToFilterPath(string path, bool isFolder) - { - string filterPath = - path.StartsWith("*") - ? path - : path.Replace(ScalarConstants.GitPathSeparator, Path.DirectorySeparatorChar).TrimStart(Path.DirectorySeparatorChar); - - if (isFolder && filterPath.Length > 0 && !filterPath.EndsWith(pathSeparatorString)) - { - filterPath += pathSeparatorString; - } - - return filterPath; - } - - private bool IsSymbolicRef(string targetCommitish) - { - return targetCommitish.StartsWith("refs/", StringComparison.OrdinalIgnoreCase); - } - - private void SavePrefetchArgs(string targetCommit) - { - if (this.lastPrefetchArgs != null) - { - this.lastPrefetchArgs.SetValuesAndFlush( - new[] - { - new KeyValuePair(PrefetchArgs.CommitId, targetCommit), - new KeyValuePair(PrefetchArgs.Files, JsonConvert.SerializeObject(this.FileList)), - new KeyValuePair(PrefetchArgs.Folders, JsonConvert.SerializeObject(this.FolderList)), - }); - } - } - - public class FetchException : Exception - { - public FetchException(string format, params object[] args) - : base(string.Format(format, args)) - { - } - } - - private static class PrefetchArgs - { - public const string CommitId = "CommitId"; - public const string Files = "Files"; - public const string Folders = "Folders"; - } - } -} diff --git a/Scalar.Common/Prefetch/Git/DiffHelper.cs b/Scalar.Common/Prefetch/Git/DiffHelper.cs deleted file mode 100644 index 06a097c02f..0000000000 --- a/Scalar.Common/Prefetch/Git/DiffHelper.cs +++ /dev/null @@ -1,541 +0,0 @@ -using Scalar.Common.Git; -using Scalar.Common.Tracing; -using System; -using System.Collections.Concurrent; -using System.Collections.Generic; -using System.IO; -using System.Linq; -using System.Text; - -namespace Scalar.Common.Prefetch.Git -{ - public class DiffHelper - { - private const string AreaPath = nameof(DiffHelper); - - private ITracer tracer; - private HashSet exactFileList; - private List patternList; - - // The maximum depth of any path provided in 'fileList' - private int maxIncludedFolderPathDepth; - - // All paths provided in 'fileList', these are treated as recusive - private HashSet includedRecursiveFolders; - - // The parents of all folders 'fileList'. Immediate children of these - // folders are also included when folders are specified. - private HashSet includedFolderParents; - - private HashSet filesAdded = new HashSet(StringComparer.OrdinalIgnoreCase); - - private HashSet stagedDirectoryOperations = new HashSet(new DiffTreeByNameComparer()); - private HashSet stagedFileDeletes = new HashSet(StringComparer.OrdinalIgnoreCase); - - private Enlistment enlistment; - private GitProcess git; - - public DiffHelper(ITracer tracer, Enlistment enlistment, IEnumerable fileList, IEnumerable folderList, bool includeSymLinks) - : this(tracer, enlistment, new GitProcess(enlistment), fileList, folderList, includeSymLinks) - { - } - - public DiffHelper(ITracer tracer, Enlistment enlistment, GitProcess git, IEnumerable fileList, IEnumerable folderList, bool includeSymLinks) - { - this.tracer = tracer; - this.exactFileList = new HashSet(fileList.Where(x => !x.StartsWith("*")), StringComparer.OrdinalIgnoreCase); - this.patternList = fileList.Where(x => x.StartsWith("*")).ToList(); - - GenerateRecursiveAndParentPathSets( - folderList, - out this.includedFolderParents, - out this.includedRecursiveFolders, - out this.maxIncludedFolderPathDepth); - - this.enlistment = enlistment; - this.git = git; - this.ShouldIncludeSymLinks = includeSymLinks; - - this.DirectoryOperations = new ConcurrentQueue(); - this.FileDeleteOperations = new ConcurrentQueue(); - this.FileAddOperations = new ConcurrentDictionary>(StringComparer.OrdinalIgnoreCase); - this.RequiredBlobs = new BlockingCollection(); - } - - public bool ShouldIncludeSymLinks { get; set; } - - public bool HasFailures { get; private set; } - - public ConcurrentQueue DirectoryOperations { get; } - - public ConcurrentQueue FileDeleteOperations { get; } - - /// - /// Mapping from available sha to filenames where blob should be written - /// - public ConcurrentDictionary> FileAddOperations { get; } - - /// - /// Blobs required to perform a checkout of the destination - /// - public BlockingCollection RequiredBlobs { get; } - - public int TotalDirectoryOperations - { - get { return this.stagedDirectoryOperations.Count; } - } - - public int TotalFileDeletes - { - get { return this.stagedFileDeletes.Count; } - } - - /// - /// Returns true if the whole tree was updated - /// - public bool UpdatedWholeTree { get; internal set; } = false; - - // public for unit tests - public static void GenerateRecursiveAndParentPathSets( - IEnumerable folderList, - out HashSet parentFolders, - out HashSet recursiveFolders, - out int maxFolderPathDepth) - { - // Every path in folderList is a recursive path - recursiveFolders = new HashSet(folderList, StringComparer.OrdinalIgnoreCase); - - // Build a hash set that contains all of the parents of the paths in folderList - maxFolderPathDepth = 0; - parentFolders = new HashSet(StringComparer.OrdinalIgnoreCase); - StringBuilder parentPaths = new StringBuilder(capacity: ScalarConstants.MaxPath); - foreach (string folderPath in folderList) - { - string[] pathParts = folderPath.Split(new char[] { Path.DirectorySeparatorChar }, StringSplitOptions.RemoveEmptyEntries); - - if (pathParts.Length > maxFolderPathDepth) - { - maxFolderPathDepth = pathParts.Length; - } - - // Check 'pathParts.Length - 1' because the full folder path is already included in recursiveFolders. - // There is no need to add it to parentFolders as well. - for (int pathIndex = 0; pathIndex < pathParts.Length - 1; ++pathIndex) - { - parentPaths.Append(pathParts[pathIndex]); - parentPaths.Append(Path.DirectorySeparatorChar); - parentFolders.Add(parentPaths.ToString()); - } - - parentPaths.Clear(); - } - } - - public void PerformDiff(string targetCommitSha) - { - string targetTreeSha; - string headTreeSha; - using (LibGit2Repo repo = new LibGit2Repo(this.tracer, this.enlistment.WorkingDirectoryBackingRoot)) - { - targetTreeSha = repo.GetTreeSha(targetCommitSha); - headTreeSha = repo.GetTreeSha("HEAD"); - } - - this.PerformDiff(headTreeSha, targetTreeSha); - } - - public void PerformDiff(string sourceTreeSha, string targetTreeSha) - { - EventMetadata metadata = new EventMetadata(); - metadata.Add("TargetTreeSha", targetTreeSha); - metadata.Add("HeadTreeSha", sourceTreeSha); - using (ITracer activity = this.tracer.StartActivity("PerformDiff", EventLevel.Informational, Keywords.Telemetry, metadata)) - { - metadata = new EventMetadata(); - if (sourceTreeSha == null) - { - this.UpdatedWholeTree = true; - - // Nothing is checked out (fresh git init), so we must search the entire tree. - GitProcess.Result result = this.git.LsTree( - targetTreeSha, - line => this.EnqueueOperationsFromLsTreeLine(activity, line), - recursive: true, - showAllTrees: true); - - if (result.ExitCodeIsFailure) - { - this.HasFailures = true; - metadata.Add("Errors", result.Errors); - metadata.Add("Output", result.Output.Length > 1024 ? result.Output.Substring(1024) : result.Output); - } - - metadata.Add("Operation", "LsTree"); - } - else - { - // Diff head and target, determine what needs to be done. - GitProcess.Result result = this.git.DiffTree( - sourceTreeSha, - targetTreeSha, - line => this.EnqueueOperationsFromDiffTreeLine(this.tracer, line)); - - if (result.ExitCodeIsFailure) - { - this.HasFailures = true; - metadata.Add("Errors", result.Errors); - metadata.Add("Output", result.Output.Length > 1024 ? result.Output.Substring(1024) : result.Output); - } - - metadata.Add("Operation", "DiffTree"); - } - - this.FlushStagedQueues(); - - metadata.Add("Success", !this.HasFailures); - metadata.Add("DirectoryOperationsCount", this.TotalDirectoryOperations); - metadata.Add("FileDeleteOperationsCount", this.TotalFileDeletes); - metadata.Add("RequiredBlobsCount", this.RequiredBlobs.Count); - metadata.Add("FileAddOperationsCount", this.FileAddOperations.Sum(kvp => kvp.Value.Count)); - activity.Stop(metadata); - } - } - - public void ParseDiffFile(string filename) - { - using (ITracer activity = this.tracer.StartActivity("PerformDiff", EventLevel.Informational)) - { - using (StreamReader file = new StreamReader(File.OpenRead(filename))) - { - while (!file.EndOfStream) - { - this.EnqueueOperationsFromDiffTreeLine(activity, file.ReadLine()); - } - } - - this.FlushStagedQueues(); - } - } - - // public for unit testing - /// - /// Return true if the specific file path should be included in the cone specified - /// by the folderList that was provided when constructing the DiffHelper. - /// - /// Path to a file to compare against the folder list - /// true if the file path is included in the folders list and false otherwise - public bool PathMatchesFolders(string filePath) - { - if (this.maxIncludedFolderPathDepth == 0) - { - // At least one folder must be specified to for any paths to match the list - return false; - } - - int lastBlobPathSeparator = filePath.LastIndexOf(Path.DirectorySeparatorChar); - if (lastBlobPathSeparator < 0) - { - // Always include paths in the root directory - return true; - } - - string parentPath = filePath.Substring(0, lastBlobPathSeparator + 1); - if (this.includedFolderParents.Contains(parentPath)) - { - return true; - } - - // Check ancestors of filePath against the recursive set of folders - // maxIncludedFolderPathDepth stores the maximum depth of folders in includedRecursiveFolders - // so that we can avoid checking folders too deep to be in the set - // - // Example: - // - // includedRecursiveFolders -> { "A\", "D\E\F\" } - // maxIncludedFolderPathDepth -> 3 - // - // - // When checking if the ancestors of "G\H\I\J\K\L\m.txt" are in includedRecursiveFolders - // there is no need to check beyond "G\H\I\" because includedRecursiveFolders does - // not contains any paths more the 3 levels deep. - int pathSeparatorIndex = 0; - for (int i = 0; i < this.maxIncludedFolderPathDepth; ++i) - { - pathSeparatorIndex = filePath.IndexOf(Path.DirectorySeparatorChar, startIndex: pathSeparatorIndex); - if (pathSeparatorIndex < 0) - { - // We've tested every ancestor folder of filePath and not found a match - return false; - } - - string ancestorPath = filePath.Substring(0, pathSeparatorIndex + 1); - if (this.includedRecursiveFolders.Contains(ancestorPath)) - { - return true; - } - - ++pathSeparatorIndex; - } - - return false; - } - - private void FlushStagedQueues() - { - List deletedPaths = new List(); - foreach (DiffTreeResult result in this.stagedDirectoryOperations) - { - // Don't enqueue deletes that will be handled by recursively deleting their parent. - // Git traverses diffs in pre-order, so we are guaranteed to ignore child deletes here. - if (result.Operation == DiffTreeResult.Operations.Delete) - { - if (deletedPaths.Any(path => result.TargetPath.StartsWith(path, StringComparison.OrdinalIgnoreCase))) - { - continue; - } - - deletedPaths.Add(result.TargetPath); - } - - this.DirectoryOperations.Enqueue(result); - } - - foreach (string filePath in this.stagedFileDeletes) - { - if (deletedPaths.Any(path => filePath.StartsWith(path, StringComparison.OrdinalIgnoreCase))) - { - continue; - } - - deletedPaths.Add(filePath); - - this.FileDeleteOperations.Enqueue(filePath); - } - - this.RequiredBlobs.CompleteAdding(); - } - - private void EnqueueOperationsFromLsTreeLine(ITracer activity, string line) - { - DiffTreeResult result = DiffTreeResult.ParseFromLsTreeLine(line); - if (result == null) - { - this.tracer.RelatedError("Unrecognized ls-tree line: {0}", line); - } - - if (!this.ShouldIncludeResult(result)) - { - return; - } - - if (result.TargetIsDirectory) - { - if (!this.stagedDirectoryOperations.Add(result)) - { - EventMetadata metadata = new EventMetadata(); - metadata.Add(nameof(result.TargetPath), result.TargetPath); - metadata.Add(TracingConstants.MessageKey.WarningMessage, "File exists in tree with two different cases. Taking the last one."); - this.tracer.RelatedEvent(EventLevel.Warning, "CaseConflict", metadata); - - // Since we match only on filename, re-adding is the easiest way to update the set. - this.stagedDirectoryOperations.Remove(result); - this.stagedDirectoryOperations.Add(result); - } - } - else - { - this.EnqueueFileAddOperation(activity, result); - } - } - - private void EnqueueOperationsFromDiffTreeLine(ITracer activity, string line) - { - if (!line.StartsWith(":")) - { - // Diff-tree starts with metadata we can ignore. - // Real diff lines always start with a colon - return; - } - - DiffTreeResult result = DiffTreeResult.ParseFromDiffTreeLine(line); - if (!this.ShouldIncludeResult(result)) - { - return; - } - - if (result.Operation == DiffTreeResult.Operations.Unknown || - result.Operation == DiffTreeResult.Operations.Unmerged || - result.Operation == DiffTreeResult.Operations.CopyEdit || - result.Operation == DiffTreeResult.Operations.RenameEdit) - { - EventMetadata metadata = new EventMetadata(); - metadata.Add(nameof(result.TargetPath), result.TargetPath); - metadata.Add(nameof(line), line); - activity.RelatedError(metadata, "Unexpected diff operation: " + result.Operation); - this.HasFailures = true; - return; - } - - // Separate and enqueue all directory operations first. - if (result.SourceIsDirectory || result.TargetIsDirectory) - { - switch (result.Operation) - { - case DiffTreeResult.Operations.Delete: - if (!this.stagedDirectoryOperations.Add(result)) - { - EventMetadata metadata = new EventMetadata(); - metadata.Add(nameof(result.TargetPath), result.TargetPath); - metadata.Add(TracingConstants.MessageKey.WarningMessage, "A case change was attempted. It will not be reflected in the working directory."); - activity.RelatedEvent(EventLevel.Warning, "CaseConflict", metadata); - } - - break; - case DiffTreeResult.Operations.Add: - case DiffTreeResult.Operations.Modify: - if (!this.stagedDirectoryOperations.Add(result)) - { - EventMetadata metadata = new EventMetadata(); - metadata.Add(nameof(result.TargetPath), result.TargetPath); - metadata.Add(TracingConstants.MessageKey.WarningMessage, "A case change was attempted. It will not be reflected in the working directory."); - activity.RelatedEvent(EventLevel.Warning, "CaseConflict", metadata); - - // Replace the delete with the add to make sure we don't delete a folder from under ourselves - this.stagedDirectoryOperations.Remove(result); - this.stagedDirectoryOperations.Add(result); - } - - break; - default: - activity.RelatedError("Unexpected diff operation from line: {0}", line); - break; - } - } - else - { - switch (result.Operation) - { - case DiffTreeResult.Operations.Delete: - this.EnqueueFileDeleteOperation(activity, result.TargetPath); - - break; - case DiffTreeResult.Operations.Modify: - case DiffTreeResult.Operations.Add: - this.EnqueueFileAddOperation(activity, result); - break; - default: - activity.RelatedError("Unexpected diff operation from line: {0}", line); - break; - } - } - } - - private bool ShouldIncludeResult(DiffTreeResult blobAdd) - { - if (blobAdd.TargetIsSymLink && !this.ShouldIncludeSymLinks) - { - return false; - } - - if (blobAdd.TargetPath == null) - { - return true; - } - - if (this.exactFileList.Count == 0 && - this.patternList.Count == 0 && - this.maxIncludedFolderPathDepth == 0) - { - return true; - } - - if (this.exactFileList.Contains(blobAdd.TargetPath) || - this.patternList.Any(path => blobAdd.TargetPath.EndsWith(path.Substring(1), StringComparison.OrdinalIgnoreCase))) - { - return true; - } - - return this.PathMatchesFolders(blobAdd.TargetPath); - } - - private void EnqueueFileDeleteOperation(ITracer activity, string targetPath) - { - if (this.filesAdded.Contains(targetPath)) - { - EventMetadata metadata = new EventMetadata(); - metadata.Add(nameof(targetPath), targetPath); - metadata.Add(TracingConstants.MessageKey.WarningMessage, "A case change was attempted. It will not be reflected in the working directory."); - activity.RelatedEvent(EventLevel.Warning, "CaseConflict", metadata); - - return; - } - - this.stagedFileDeletes.Add(targetPath); - } - - /// - /// This is not used in a multithreaded method, it doesn't need to be thread-safe - /// - private void EnqueueFileAddOperation(ITracer activity, DiffTreeResult operation) - { - // Each filepath should be case-insensitive unique. If there are duplicates, only the last parsed one should remain. - if (!this.filesAdded.Add(operation.TargetPath)) - { - foreach (KeyValuePair> kvp in this.FileAddOperations) - { - PathWithMode tempPathWithMode = new PathWithMode(operation.TargetPath, 0x0000); - if (kvp.Value.Remove(tempPathWithMode)) - { - break; - } - } - } - - if (this.stagedFileDeletes.Remove(operation.TargetPath)) - { - EventMetadata metadata = new EventMetadata(); - metadata.Add(nameof(operation.TargetPath), operation.TargetPath); - metadata.Add(TracingConstants.MessageKey.WarningMessage, "A case change was attempted. It will not be reflected in the working directory."); - activity.RelatedEvent(EventLevel.Warning, "CaseConflict", metadata); - } - - this.FileAddOperations.AddOrUpdate( - operation.TargetSha, - new HashSet { new PathWithMode(operation.TargetPath, operation.TargetMode) }, - (key, oldValue) => - { - oldValue.Add(new PathWithMode(operation.TargetPath, operation.TargetMode)); - return oldValue; - }); - - this.RequiredBlobs.Add(operation.TargetSha); - } - - private class DiffTreeByNameComparer : IEqualityComparer - { - public bool Equals(DiffTreeResult x, DiffTreeResult y) - { - if (x.TargetPath != null) - { - if (y.TargetPath != null) - { - return x.TargetPath.Equals(y.TargetPath, StringComparison.OrdinalIgnoreCase); - } - - return false; - } - else - { - // both null means they're equal - return y.TargetPath == null; - } - } - - public int GetHashCode(DiffTreeResult obj) - { - return obj.TargetPath != null ? - StringComparer.OrdinalIgnoreCase.GetHashCode(obj.TargetPath) : 0; - } - } - } -} diff --git a/Scalar.Common/Prefetch/Git/PathWithMode.cs b/Scalar.Common/Prefetch/Git/PathWithMode.cs deleted file mode 100644 index cd53a853aa..0000000000 --- a/Scalar.Common/Prefetch/Git/PathWithMode.cs +++ /dev/null @@ -1,33 +0,0 @@ -using System; - -namespace Scalar.Common.Prefetch.Git -{ - public class PathWithMode - { - public PathWithMode(string path, ushort mode) - { - this.Path = path; - this.Mode = mode; - } - - public ushort Mode { get; } - public string Path { get; } - - public override bool Equals(object obj) - { - PathWithMode x = obj as PathWithMode; - - if (x == null) - { - return false; - } - - return x.Path.Equals(this.Path, StringComparison.OrdinalIgnoreCase); - } - - public override int GetHashCode() - { - return StringComparer.OrdinalIgnoreCase.GetHashCode(this.Path); - } - } -} diff --git a/Scalar.Common/Prefetch/Git/PrefetchGitObjects.cs b/Scalar.Common/Prefetch/Git/PrefetchGitObjects.cs deleted file mode 100644 index c7378c398f..0000000000 --- a/Scalar.Common/Prefetch/Git/PrefetchGitObjects.cs +++ /dev/null @@ -1,14 +0,0 @@ -using Scalar.Common.FileSystem; -using Scalar.Common.Git; -using Scalar.Common.Http; -using Scalar.Common.Tracing; - -namespace Scalar.Common.Prefetch.Git -{ - public class PrefetchGitObjects : GitObjects - { - public PrefetchGitObjects(ITracer tracer, Enlistment enlistment, GitObjectsHttpRequestor objectRequestor, PhysicalFileSystem fileSystem = null) : base(tracer, enlistment, objectRequestor, fileSystem) - { - } - } -} diff --git a/Scalar.Common/Prefetch/Pipeline/BatchObjectDownloadStage.cs b/Scalar.Common/Prefetch/Pipeline/BatchObjectDownloadStage.cs deleted file mode 100644 index ea91ef43f3..0000000000 --- a/Scalar.Common/Prefetch/Pipeline/BatchObjectDownloadStage.cs +++ /dev/null @@ -1,244 +0,0 @@ -using Scalar.Common.Git; -using Scalar.Common.Http; -using Scalar.Common.NetworkStreams; -using Scalar.Common.Prefetch.Pipeline.Data; -using Scalar.Common.Tracing; -using System; -using System.Collections.Concurrent; -using System.Collections.Generic; -using System.IO; -using System.Linq; -using System.Threading; - -namespace Scalar.Common.Prefetch.Pipeline -{ - /// - /// Takes in blocks of object shas, downloads object shas as a pack or loose object, outputs pack locations (if applicable). - /// - public class BatchObjectDownloadStage : PrefetchPipelineStage - { - private const string AreaPath = nameof(BatchObjectDownloadStage); - private const string DownloadAreaPath = "Download"; - - private static readonly TimeSpan HeartBeatPeriod = TimeSpan.FromSeconds(20); - - private readonly DownloadRequestAggregator downloadRequests; - - private int activeDownloadCount; - - private ITracer tracer; - private Enlistment enlistment; - private GitObjectsHttpRequestor objectRequestor; - private GitObjects gitObjects; - private Timer heartbeat; - - private long bytesDownloaded = 0; - - public BatchObjectDownloadStage( - int maxParallel, - int chunkSize, - BlockingCollection missingBlobs, - BlockingCollection availableBlobs, - ITracer tracer, - Enlistment enlistment, - GitObjectsHttpRequestor objectRequestor, - GitObjects gitObjects) - : base(maxParallel) - { - this.tracer = tracer.StartActivity(AreaPath, EventLevel.Informational, Keywords.Telemetry, metadata: null); - - this.downloadRequests = new DownloadRequestAggregator(missingBlobs, chunkSize); - - this.enlistment = enlistment; - this.objectRequestor = objectRequestor; - - this.gitObjects = gitObjects; - - this.AvailablePacks = new BlockingCollection(); - this.AvailableObjects = availableBlobs; - } - - public BlockingCollection AvailablePacks { get; } - - public BlockingCollection AvailableObjects { get; } - - protected override void DoBeforeWork() - { - this.heartbeat = new Timer(this.EmitHeartbeat, null, TimeSpan.Zero, HeartBeatPeriod); - base.DoBeforeWork(); - } - - protected override void DoWork() - { - BlobDownloadRequest request; - while (this.downloadRequests.TryTake(out request)) - { - Interlocked.Increment(ref this.activeDownloadCount); - - EventMetadata metadata = new EventMetadata(); - metadata.Add("RequestId", request.RequestId); - metadata.Add("ActiveDownloads", this.activeDownloadCount); - metadata.Add("NumberOfObjects", request.ObjectIds.Count); - - using (ITracer activity = this.tracer.StartActivity(DownloadAreaPath, EventLevel.Informational, Keywords.Telemetry, metadata)) - { - try - { - HashSet successfulDownloads = new HashSet(StringComparer.OrdinalIgnoreCase); - RetryWrapper.InvocationResult result = this.objectRequestor.TryDownloadObjects( - () => request.ObjectIds.Except(successfulDownloads), - onSuccess: (tryCount, response) => this.WriteObjectOrPack(request, tryCount, response, successfulDownloads), - onFailure: RetryWrapper.StandardErrorHandler(activity, request.RequestId, DownloadAreaPath), - preferBatchedLooseObjects: true); - - if (!result.Succeeded) - { - this.HasFailures = true; - } - - metadata.Add("Success", result.Succeeded); - metadata.Add("AttemptNumber", result.Attempts); - metadata["ActiveDownloads"] = this.activeDownloadCount - 1; - activity.Stop(metadata); - } - finally - { - Interlocked.Decrement(ref this.activeDownloadCount); - } - } - } - } - - protected override void DoAfterWork() - { - this.heartbeat.Dispose(); - this.heartbeat = null; - - this.AvailablePacks.CompleteAdding(); - EventMetadata metadata = new EventMetadata(); - metadata.Add("RequestCount", BlobDownloadRequest.TotalRequests); - metadata.Add("BytesDownloaded", this.bytesDownloaded); - this.tracer.Stop(metadata); - } - - private RetryWrapper.CallbackResult WriteObjectOrPack( - BlobDownloadRequest request, - int tryCount, - GitEndPointResponseData response, - HashSet successfulDownloads = null) - { - // To reduce allocations, reuse the same buffer when writing objects in this batch - byte[] bufToCopyWith = new byte[StreamUtil.DefaultCopyBufferSize]; - - string fileName = null; - switch (response.ContentType) - { - case GitObjectContentType.LooseObject: - string sha = request.ObjectIds.First(); - fileName = this.gitObjects.WriteLooseObject( - response.Stream, - sha, - overwriteExistingObject: false, - bufToCopyWith: bufToCopyWith); - this.AvailableObjects.Add(sha); - break; - case GitObjectContentType.PackFile: - fileName = this.gitObjects.WriteTempPackFile(response.Stream); - this.AvailablePacks.Add(new IndexPackRequest(fileName, request)); - break; - case GitObjectContentType.BatchedLooseObjects: - BatchedLooseObjectDeserializer.OnLooseObject onLooseObject = (objectStream, sha1) => - { - this.gitObjects.WriteLooseObject( - objectStream, - sha1, - overwriteExistingObject: false, - bufToCopyWith: bufToCopyWith); - this.AvailableObjects.Add(sha1); - - if (successfulDownloads != null) - { - successfulDownloads.Add(sha1); - } - - // This isn't strictly correct because we don't add object header bytes, - // just the actual compressed content length, but we expect the amount of - // header data to be negligible compared to the objects themselves. - Interlocked.Add(ref this.bytesDownloaded, objectStream.Length); - }; - - new BatchedLooseObjectDeserializer(response.Stream, onLooseObject).ProcessObjects(); - break; - } - - if (fileName != null) - { - // NOTE: If we are writing a file as part of this method, the only case - // where it's not expected to exist is when running unit tests - FileInfo info = new FileInfo(fileName); - if (info.Exists) - { - Interlocked.Add(ref this.bytesDownloaded, info.Length); - } - else - { - return new RetryWrapper.CallbackResult( - new GitObjectsHttpRequestor.GitObjectTaskResult(false)); - } - } - - return new RetryWrapper.CallbackResult( - new GitObjectsHttpRequestor.GitObjectTaskResult(true)); - } - - private void EmitHeartbeat(object state) - { - EventMetadata metadata = new EventMetadata(); - metadata["ActiveDownloads"] = this.activeDownloadCount; - this.tracer.RelatedEvent(EventLevel.Verbose, "DownloadHeartbeat", metadata); - } - - private class DownloadRequestAggregator - { - private BlockingCollection missingBlobs; - private int chunkSize; - - public DownloadRequestAggregator(BlockingCollection missingBlobs, int chunkSize) - { - this.missingBlobs = missingBlobs; - this.chunkSize = chunkSize; - } - - public bool TryTake(out BlobDownloadRequest request) - { - List blobsInChunk = new List(); - - for (int i = 0; i < this.chunkSize; ++i) - { - // Only wait a short while for new work to show up, otherwise go ahead and download what we have accumulated so far - const int TimeoutMs = 100; - - string blobId; - if (this.missingBlobs.TryTake(out blobId, TimeoutMs)) - { - blobsInChunk.Add(blobId); - } - else if (blobsInChunk.Count > 0 || - this.missingBlobs.IsAddingCompleted) - { - break; - } - } - - if (blobsInChunk.Count > 0) - { - request = new BlobDownloadRequest(blobsInChunk); - return true; - } - - request = null; - return false; - } - } - } -} diff --git a/Scalar.Common/Prefetch/Pipeline/Data/BlobDownloadRequest.cs b/Scalar.Common/Prefetch/Pipeline/Data/BlobDownloadRequest.cs deleted file mode 100644 index 447c974081..0000000000 --- a/Scalar.Common/Prefetch/Pipeline/Data/BlobDownloadRequest.cs +++ /dev/null @@ -1,28 +0,0 @@ -using System.Collections.Generic; -using System.Threading; - -namespace Scalar.Common.Prefetch.Pipeline.Data -{ - public class BlobDownloadRequest - { - private static int requestCounter = 0; - - public BlobDownloadRequest(IReadOnlyList objectIds) - { - this.ObjectIds = objectIds; - this.RequestId = Interlocked.Increment(ref requestCounter); - } - - public static int TotalRequests - { - get - { - return requestCounter; - } - } - - public IReadOnlyList ObjectIds { get; } - - public int RequestId { get; } - } -} diff --git a/Scalar.Common/Prefetch/Pipeline/Data/IndexPackRequest.cs b/Scalar.Common/Prefetch/Pipeline/Data/IndexPackRequest.cs deleted file mode 100644 index bbb4d87492..0000000000 --- a/Scalar.Common/Prefetch/Pipeline/Data/IndexPackRequest.cs +++ /dev/null @@ -1,15 +0,0 @@ -namespace Scalar.Common.Prefetch.Pipeline.Data -{ - public class IndexPackRequest - { - public IndexPackRequest(string tempPackFile, BlobDownloadRequest downloadRequest) - { - this.TempPackFile = tempPackFile; - this.DownloadRequest = downloadRequest; - } - - public BlobDownloadRequest DownloadRequest { get; } - - public string TempPackFile { get; } - } -} diff --git a/Scalar.Common/Prefetch/Pipeline/FindBlobsStage.cs b/Scalar.Common/Prefetch/Pipeline/FindBlobsStage.cs deleted file mode 100644 index b08afe09df..0000000000 --- a/Scalar.Common/Prefetch/Pipeline/FindBlobsStage.cs +++ /dev/null @@ -1,89 +0,0 @@ -using Scalar.Common.Git; -using Scalar.Common.Prefetch.Git; -using Scalar.Common.Tracing; -using System.Collections.Concurrent; -using System.Threading; - -namespace Scalar.Common.Prefetch.Pipeline -{ - /// - /// Takes in search requests, searches each tree as requested, outputs blocks of missing blob shas. - /// - public class FindBlobsStage : PrefetchPipelineStage - { - private const string AreaPath = nameof(FindBlobsStage); - - private ITracer tracer; - private Enlistment enlistment; - private int missingBlobCount; - private int availableBlobCount; - - private BlockingCollection requiredBlobs; - - private ConcurrentHashSet alreadyFoundBlobIds; - - public FindBlobsStage( - int maxParallel, - BlockingCollection requiredBlobs, - BlockingCollection availableBlobs, - ITracer tracer, - Enlistment enlistment) - : base(maxParallel) - { - this.tracer = tracer.StartActivity(AreaPath, EventLevel.Informational, Keywords.Telemetry, metadata: null); - this.requiredBlobs = requiredBlobs; - this.enlistment = enlistment; - this.alreadyFoundBlobIds = new ConcurrentHashSet(); - - this.MissingBlobs = new BlockingCollection(); - this.AvailableBlobs = availableBlobs; - } - - public BlockingCollection MissingBlobs { get; } - public BlockingCollection AvailableBlobs { get; } - - public int MissingBlobCount - { - get { return this.missingBlobCount; } - } - - public int AvailableBlobCount - { - get { return this.availableBlobCount; } - } - - protected override void DoWork() - { - string blobId; - using (LibGit2Repo repo = new LibGit2Repo(this.tracer, this.enlistment.WorkingDirectoryBackingRoot)) - { - while (this.requiredBlobs.TryTake(out blobId, Timeout.Infinite)) - { - if (this.alreadyFoundBlobIds.Add(blobId)) - { - if (!repo.ObjectExists(blobId)) - { - Interlocked.Increment(ref this.missingBlobCount); - this.MissingBlobs.Add(blobId); - } - else - { - Interlocked.Increment(ref this.availableBlobCount); - this.AvailableBlobs.Add(blobId); - } - } - } - } - } - - protected override void DoAfterWork() - { - this.MissingBlobs.CompleteAdding(); - - EventMetadata metadata = new EventMetadata(); - metadata.Add("TotalMissingObjects", this.missingBlobCount); - metadata.Add("AvailableObjects", this.availableBlobCount); - this.tracer.Stop(metadata); - } - } -} diff --git a/Scalar.Common/Prefetch/Pipeline/IndexPackStage.cs b/Scalar.Common/Prefetch/Pipeline/IndexPackStage.cs deleted file mode 100644 index 7ed42765a1..0000000000 --- a/Scalar.Common/Prefetch/Pipeline/IndexPackStage.cs +++ /dev/null @@ -1,77 +0,0 @@ -using Scalar.Common.Git; -using Scalar.Common.Prefetch.Pipeline.Data; -using Scalar.Common.Tracing; -using System.Collections.Concurrent; -using System.Threading; - -namespace Scalar.Common.Prefetch.Pipeline -{ - public class IndexPackStage : PrefetchPipelineStage - { - private const string AreaPath = nameof(IndexPackStage); - private const string IndexPackAreaPath = "IndexPack"; - - private readonly BlockingCollection availablePacks; - - private ITracer tracer; - private GitObjects gitObjects; - - private long shasIndexed = 0; - - public IndexPackStage( - int maxParallel, - BlockingCollection availablePacks, - BlockingCollection availableBlobs, - ITracer tracer, - GitObjects gitObjects) - : base(maxParallel) - { - this.tracer = tracer.StartActivity(AreaPath, EventLevel.Informational, Keywords.Telemetry, metadata: null); - this.availablePacks = availablePacks; - this.gitObjects = gitObjects; - this.AvailableBlobs = availableBlobs; - } - - public BlockingCollection AvailableBlobs { get; } - - protected override void DoWork() - { - IndexPackRequest request; - while (this.availablePacks.TryTake(out request, Timeout.Infinite)) - { - EventMetadata metadata = new EventMetadata(); - metadata.Add("RequestId", request.DownloadRequest.RequestId); - using (ITracer activity = this.tracer.StartActivity(IndexPackAreaPath, EventLevel.Informational, Keywords.Telemetry, metadata)) - { - GitProcess.Result result = this.gitObjects.IndexTempPackFile(request.TempPackFile); - if (result.ExitCodeIsFailure) - { - EventMetadata errorMetadata = new EventMetadata(); - errorMetadata.Add("RequestId", request.DownloadRequest.RequestId); - activity.RelatedError(errorMetadata, result.Errors); - this.HasFailures = true; - } - - if (!this.HasFailures) - { - foreach (string blobId in request.DownloadRequest.ObjectIds) - { - this.AvailableBlobs.Add(blobId); - Interlocked.Increment(ref this.shasIndexed); - } - } - - metadata.Add("Success", !this.HasFailures); - activity.Stop(metadata); - } - } - } - - protected override void DoAfterWork() - { - EventMetadata metadata = new EventMetadata(); - metadata.Add("ShasIndexed", this.shasIndexed); - this.tracer.Stop(metadata); - } - } -} diff --git a/Scalar.Common/Prefetch/Pipeline/PrefetchPipelineStage.cs b/Scalar.Common/Prefetch/Pipeline/PrefetchPipelineStage.cs deleted file mode 100644 index d2197a8598..0000000000 --- a/Scalar.Common/Prefetch/Pipeline/PrefetchPipelineStage.cs +++ /dev/null @@ -1,61 +0,0 @@ -using System; -using System.Threading; - -namespace Scalar.Common.Prefetch.Pipeline -{ - public abstract class PrefetchPipelineStage - { - private int maxParallel; - private Thread[] workers; - - public PrefetchPipelineStage(int maxParallel) - { - this.maxParallel = maxParallel; - } - - public bool HasFailures { get; protected set; } - - public void Start() - { - if (this.workers != null) - { - throw new InvalidOperationException("Cannot call start twice"); - } - - this.DoBeforeWork(); - - this.workers = new Thread[this.maxParallel]; - for (int i = 0; i < this.workers.Length; ++i) - { - this.workers[i] = new Thread(this.DoWork); - this.workers[i].Start(); - } - } - - public void WaitForCompletion() - { - if (this.workers == null) - { - throw new InvalidOperationException("Cannot wait for completion before start is called"); - } - - foreach (Thread t in this.workers) - { - t.Join(); - } - - this.DoAfterWork(); - this.workers = null; - } - - protected virtual void DoBeforeWork() - { - } - - protected abstract void DoWork(); - - protected virtual void DoAfterWork() - { - } - } -} diff --git a/Scalar.Common/ScalarConstants.cs b/Scalar.Common/ScalarConstants.cs index 06129a42e8..3cfa2d1a84 100644 --- a/Scalar.Common/ScalarConstants.cs +++ b/Scalar.Common/ScalarConstants.cs @@ -36,6 +36,7 @@ public static class GitConfig public const string ScalarTelemetryPipe = GitConfig.ScalarPrefix + "telemetry-pipe"; public const string IKey = GitConfig.ScalarPrefix + "ikey"; public const string HooksExtension = ".hooks"; + public const string UseGvfsHelper = "core.useGvfsHelper"; } public static class LocalScalarConfig diff --git a/Scalar.Common/ScalarPlatform.cs b/Scalar.Common/ScalarPlatform.cs index 97f440633b..3e9353119e 100644 --- a/Scalar.Common/ScalarPlatform.cs +++ b/Scalar.Common/ScalarPlatform.cs @@ -164,11 +164,6 @@ public abstract class ScalarPlatformConstants /// public abstract HashSet UpgradeBlockingProcesses { get; } - public string ScalarReadObjectHookExecutableName - { - get { return "Scalar.ReadObjectHook" + this.ExecutableExtension; } - } - public string MountExecutableName { get { return "Scalar.Mount" + this.ExecutableExtension; } diff --git a/Scalar.FunctionalTests/Tests/EnlistmentPerFixture/MountTests.cs b/Scalar.FunctionalTests/Tests/EnlistmentPerFixture/MountTests.cs index dc2f5fdaca..4d80e96285 100644 --- a/Scalar.FunctionalTests/Tests/EnlistmentPerFixture/MountTests.cs +++ b/Scalar.FunctionalTests/Tests/EnlistmentPerFixture/MountTests.cs @@ -37,19 +37,6 @@ public void MountFailsOutsideEnlistment() this.MountShouldFail("is not a valid Scalar enlistment", Path.GetDirectoryName(this.Enlistment.EnlistmentRoot)); } - [TestCase] - public void MountCopiesMissingReadObjectHook() - { - this.Enlistment.UnmountScalar(); - - string readObjectPath = this.Enlistment.GetSourcePath(".git", "hooks", "read-object" + Settings.Default.BinaryFileNameExtension); - readObjectPath.ShouldBeAFile(this.fileSystem); - this.fileSystem.DeleteFile(readObjectPath); - readObjectPath.ShouldNotExistOnDisk(this.fileSystem); - this.Enlistment.MountScalar(); - readObjectPath.ShouldBeAFile(this.fileSystem); - } - [TestCase] public void MountSetsCoreHooksPath() { diff --git a/Scalar.FunctionalTests/Tests/EnlistmentPerFixture/PrefetchVerbTests.cs b/Scalar.FunctionalTests/Tests/EnlistmentPerFixture/PrefetchVerbTests.cs index 9f7d7a5398..a234dac95a 100644 --- a/Scalar.FunctionalTests/Tests/EnlistmentPerFixture/PrefetchVerbTests.cs +++ b/Scalar.FunctionalTests/Tests/EnlistmentPerFixture/PrefetchVerbTests.cs @@ -15,7 +15,6 @@ namespace Scalar.FunctionalTests.Tests.EnlistmentPerFixture public class PrefetchVerbTests : TestsWithEnlistmentPerFixture { private const string PrefetchCommitsAndTreesLock = "prefetch-commits-trees.lock"; - private const string LsTreeTypeInPathBranchName = "FunctionalTests/20181105_LsTreeTypeInPath"; private FileSystemRunner fileSystem; @@ -24,79 +23,7 @@ public PrefetchVerbTests() this.fileSystem = new SystemIORunner(); } - [TestCase, Order(1)] - public void PrefetchAllMustBeExplicit() - { - this.Enlistment.Prefetch(string.Empty, failOnError: false).ShouldContain("Did you mean to fetch all blobs?"); - } - - [TestCase, Order(2)] - public void PrefetchSpecificFiles() - { - this.ExpectBlobCount(this.Enlistment.Prefetch($"--files {Path.Combine("GVFS", "GVFS", "Program.cs")}"), 1); - this.ExpectBlobCount(this.Enlistment.Prefetch($"--files {Path.Combine("GVFS", "GVFS", "Program.cs")};{Path.Combine("GVFS", "GVFS.FunctionalTests", "GVFS.FunctionalTests.csproj")}"), 2); - } - - [TestCase, Order(3)] - public void PrefetchByFileExtension() - { - this.ExpectBlobCount(this.Enlistment.Prefetch("--files *.cs"), 199); - this.ExpectBlobCount(this.Enlistment.Prefetch("--files *.cs;*.csproj"), 208); - } - - [TestCase, Order(4)] - public void PrefetchFolders() - { - this.ExpectBlobCount(this.Enlistment.Prefetch($"--folders {Path.Combine("GVFS", "GVFS")}"), 24); - this.ExpectBlobCount(this.Enlistment.Prefetch($"--folders {Path.Combine("GVFS", "GVFS", "CommandLine")}"), 23); - this.ExpectBlobCount(this.Enlistment.Prefetch($"--folders {Path.Combine("GVFS", "GVFS")};{Path.Combine("GVFS", "GVFS.FunctionalTests")}"), 72); - } - - [TestCase, Order(5)] - public void PrefetchNonExistentFilesAndFolders() - { - this.ExpectBlobCount(this.Enlistment.Prefetch("--files nonexistent.txt"), 0); - - // Whenever folder(s) are specified, all files in the root will match - this.ExpectBlobCount(this.Enlistment.Prefetch("--folders nonexistent_folder"), 7); - } - - [TestCase, Order(8)] - public void PrefetchFolderListFromFile() - { - string tempFilePath = Path.Combine(Path.GetTempPath(), "temp.file"); - File.WriteAllLines( - tempFilePath, - new[] - { - "# A comment", - " ", - "GVFS/", - "GVFS/GVFS", - "GVFS/" - }); - - this.ExpectBlobCount(this.Enlistment.Prefetch("--folders-list \"" + tempFilePath + "\""), 286); - File.Delete(tempFilePath); - } - - [TestCase, Order(6)] - public void PrefetchAll() - { - this.ExpectBlobCount(this.Enlistment.Prefetch("--files *"), 494); - this.ExpectBlobCount(this.Enlistment.Prefetch($"--folders {Path.DirectorySeparatorChar}"), 494); - } - - [TestCase, Order(7)] - public void NoopPrefetch() - { - this.ExpectBlobCount(this.Enlistment.Prefetch("--files *"), 494); - - this.Enlistment.Prefetch("--files *").ShouldContain("Nothing new to prefetch."); - } - - // TODO(#1219): Handle that lock files are not deleted on Mac, they are simply unlocked - [TestCase, Order(8)] + [TestCase] [Category(Categories.MacTODO.TestNeedsToLockFile)] public void PrefetchCleansUpStalePrefetchLock() { @@ -119,71 +46,6 @@ public void PrefetchCleansUpStalePrefetchLock() prefetchCommitsLockFile.ShouldNotExistOnDisk(this.fileSystem); } - [TestCase, Order(9)] - public void PrefetchFilesFromFileListFile() - { - string tempFilePath = Path.Combine(Path.GetTempPath(), "temp.file"); - try - { - File.WriteAllLines( - tempFilePath, - new[] - { - Path.Combine("GVFS", "GVFS", "Program.cs"), - Path.Combine("GVFS", "GVFS.FunctionalTests", "GVFS.FunctionalTests.csproj") - }); - - this.ExpectBlobCount(this.Enlistment.Prefetch($"--files-list \"{tempFilePath}\""), 2); - } - finally - { - File.Delete(tempFilePath); - } - } - - [TestCase, Order(10)] - public void PrefetchFilesFromFileListStdIn() - { - string input = string.Join( - Environment.NewLine, - new[] - { - Path.Combine("GVFS", "GVFS", "packages.config"), - Path.Combine("GVFS", "GVFS.FunctionalTests", "App.config") - }); - - this.ExpectBlobCount(this.Enlistment.Prefetch("--stdin-files-list", standardInput: input), 2); - } - - [TestCase, Order(11)] - public void PrefetchFolderListFromStdin() - { - string input = string.Join( - Environment.NewLine, - new[] - { - "# A comment", - " ", - "GVFS/", - "GVFS/GVFS", - "GVFS/" - }); - - this.ExpectBlobCount(this.Enlistment.Prefetch("--stdin-folders-list", standardInput: input), 286); - } - - public void PrefetchPathsWithLsTreeTypeInPath() - { - ProcessResult checkoutResult = GitProcess.InvokeProcess(this.Enlistment.RepoRoot, "checkout " + LsTreeTypeInPathBranchName); - - this.ExpectBlobCount(this.Enlistment.Prefetch("--files *"), 496); - } - - private void ExpectBlobCount(string output, int expectedCount) - { - output.ShouldContain("Matched blobs: " + expectedCount); - } - private void PostFetchStepShouldComplete() { string objectDir = this.Enlistment.GetObjectRoot(this.fileSystem); diff --git a/Scalar.FunctionalTests/Tests/EnlistmentPerFixture/SparseSetTests.cs b/Scalar.FunctionalTests/Tests/EnlistmentPerFixture/SparseSetTests.cs index aa1d9d2aea..f961323d5a 100644 --- a/Scalar.FunctionalTests/Tests/EnlistmentPerFixture/SparseSetTests.cs +++ b/Scalar.FunctionalTests/Tests/EnlistmentPerFixture/SparseSetTests.cs @@ -6,6 +6,7 @@ using System.Collections.Generic; using System.IO; using System.Linq; +using System.Text; namespace Scalar.FunctionalTests.Tests.EnlistmentPerFixture { @@ -13,7 +14,8 @@ namespace Scalar.FunctionalTests.Tests.EnlistmentPerFixture [Category(Categories.GitCommands)] public class SparseSetTests : TestsWithEnlistmentPerFixture { - private const string SetFailureMessage = "Failed to set folders to sparse-checkout"; + private const string SetOverwriteMessage = "would be overwritten by sparse checkout update"; + private const string SetIndexStateMessage = "You need to resolve your current index first"; private const string FolderDotGit = ".git"; private const string FolderDeleteFileTests = "DeleteFileTests"; @@ -39,7 +41,7 @@ public SparseSetTests() : base(fullClone: false) } [TestCase, Order(1)] - public void SparseSet() + public void InitialSparseSet() { // Simple Test Adding FileNameEncoding and verifying it exists afterwards this.VerifyDirectory(this.Enlistment.RepoRoot, new List @@ -47,10 +49,8 @@ public void SparseSet() FolderDotGit }); - ScalarProcess scalar = new ScalarProcess(this.Enlistment); - this.currentFolderList.Add(FolderFileNameEncoding); - scalar.SparseSet(this.currentFolderList); + this.SparseSet(); this.VerifyDirectory(this.Enlistment.RepoRoot, new List { @@ -63,10 +63,9 @@ public void SparseSet() public void SparseSetOneLevelDeep() { // Add GitCommands/DeleteFileTests, Verify the only directory added to GitCommands is DeleteFileTests - ScalarProcess scalar = new ScalarProcess(this.Enlistment); string addFolder = Path.Combine(FolderGitCommandsTests, FolderDeleteFileTests); this.currentFolderList.Add(addFolder); - scalar.SparseSet(this.currentFolderList); + this.SparseSet(); this.VerifyDirectory(this.Enlistment.RepoRoot, new List { @@ -85,10 +84,9 @@ public void SparseSetOneLevelDeep() [TestCase, Order(3)] public void SparseSetRemoveAFolder() { - ScalarProcess scalar = new ScalarProcess(this.Enlistment); this.currentFolderList.Remove(FolderFileNameEncoding).ShouldBeTrue("failed to remove folder from list"); - scalar.SparseSet(this.currentFolderList); + this.SparseSet(); this.VerifyDirectory(this.Enlistment.RepoRoot, new List { @@ -98,7 +96,7 @@ public void SparseSetRemoveAFolder() this.currentFolderList.Add(FolderFileNameEncoding); - scalar.SparseSet(this.currentFolderList); + this.SparseSet(); this.VerifyDirectory(this.Enlistment.RepoRoot, new List { @@ -118,9 +116,8 @@ public void SparseSetNameAlreadyExists() this.fileSystem.CreateDirectory(scriptsDirectory); this.fileSystem.CreateEmptyFile(testFile); - ScalarProcess scalar = new ScalarProcess(this.Enlistment); this.currentFolderList.Add(FolderScripts); - scalar.SparseSet(this.currentFolderList); + this.SparseSet(); this.VerifyDirectory(this.Enlistment.RepoRoot, new List { @@ -149,18 +146,17 @@ public void SparseSetFileAlreadyExists() this.VerifyContentsForSparseSetFileAlreadyExists(); // If a file already exists that would conflict with a sparse checkout, the 'set' should fail - ScalarProcess scalar = new ScalarProcess(this.Enlistment); this.currentFolderList.Add(FolderEnumerateAndReadTestFiles); - string result = scalar.SparseSet(this.currentFolderList); - result.ShouldContain(SetFailureMessage); + string result = this.SparseSet(); + result.ShouldContain(SetOverwriteMessage); // Contents should be unchanged after failure this.VerifyContentsForSparseSetFileAlreadyExists(); // After deleting the conflicting file you should be able to 'set' this.fileSystem.DeleteFile(existingFile); - result = scalar.SparseSet(this.currentFolderList); - result.ShouldNotContain(true, SetFailureMessage); + result = this.SparseSet(); + result.ShouldNotContain(true, SetOverwriteMessage); // Should now have multiple files under EnumerateAndReadTestFiles Directory.GetFiles(folderEnumerateDirectory).Length.ShouldEqual(18); @@ -176,9 +172,8 @@ public void SparseSetOnMovedFolder() string gvfsDirectory2 = this.Enlistment.GetSourcePath(gvfs2); // Add GVFS - ScalarProcess scalar = new ScalarProcess(this.Enlistment); this.currentFolderList.Add(FolderGVFS); - scalar.SparseSet(this.currentFolderList); + this.SparseSet(); this.VerifyDirectory(this.Enlistment.RepoRoot, new List { @@ -194,7 +189,7 @@ public void SparseSetOnMovedFolder() this.fileSystem.MoveDirectory(gvfsDirectory, gvfsDirectory2); // Add GVFS again - scalar.SparseSet(this.currentFolderList); + this.SparseSet(); // Only GVFS2 should exist this.VerifyDirectory(this.Enlistment.RepoRoot, new List @@ -237,11 +232,10 @@ public void SparseSetWithOneFolderConflict() this.VerifyContentsSparseSetWithOneFolderConflict(); // One folder conflict should fail the entire 'set' - ScalarProcess scalar = new ScalarProcess(this.Enlistment); this.currentFolderList.Add(FolderTest_MoveRenameFileTests); this.currentFolderList.Add(FolderTest_MoveRenameFileTests2); - string result = scalar.SparseSet(this.currentFolderList); - result.ShouldContain(SetFailureMessage); + string result = this.SparseSet(); + result.ShouldContain(SetOverwriteMessage); // Results should be unchanged this.VerifyContentsSparseSetWithOneFolderConflict(); @@ -303,10 +297,9 @@ public void AddWhileInMergeConflict() GitProcess.Invoke(this.Enlistment.RepoRoot, "cherry-pick " + commitId); // Should not be able to add which we have a merge conflict - ScalarProcess scalar = new ScalarProcess(this.Enlistment); this.currentFolderList.Add(FolderTrailingSlashTests); - string result = scalar.SparseSet(this.currentFolderList); - result.ShouldContain(SetFailureMessage); + string result = this.SparseSet(); + result.ShouldContain(SetIndexStateMessage); // New directory should not be listed because of the error this.VerifyDirectory(this.Enlistment.RepoRoot, new List @@ -349,9 +342,8 @@ public void CherryPickWithChangesInAndOutOfTheCone() GitProcess.Invoke(this.Enlistment.RepoRoot, "cherry-pick 316a387485d58d2f83cfd60dbc4fe54f5194055e"); // Add the folder with the commit out of the cone - ScalarProcess scalar = new ScalarProcess(this.Enlistment); this.currentFolderList.Add(FolderTest_WorkingDirectoryTests); - string result = scalar.SparseSet(this.currentFolderList); + this.SparseSet(); // New Folder should exist string newFolder = this.Enlistment.GetSourcePath(FolderTest_WorkingDirectoryTests); @@ -406,10 +398,9 @@ public void MergeChangesOutOfTheConeWithConflict() this.VerifyContentsMergeConflict(); // Add the folder with the conflict out of the cone - ScalarProcess scalar = new ScalarProcess(this.Enlistment); this.currentFolderList.Add(FolderTest_ConflictTests); - string result = scalar.SparseSet(this.currentFolderList); - result.ShouldNotContain(true, SetFailureMessage); + string result = this.SparseSet(); + result.ShouldNotContain(true, SetIndexStateMessage); // Now *all* files and directories should appear this.VerifyDirectory(this.Enlistment.GetSourcePath(FolderTest_ConflictTests), new List @@ -496,7 +487,6 @@ private void VerifyContentsForSparseSetFileAlreadyExists() private void VerifyDirectory(string directory, List expectedFolders) { string[] dirs = Directory.GetDirectories(directory); - dirs.Length.ShouldEqual(expectedFolders.Count); IEnumerable expectedFoldersWithPath = expectedFolders.Select(x => Path.Combine(directory, x)); Array.Sort(dirs); dirs.ShouldMatchInOrder(expectedFoldersWithPath); @@ -505,10 +495,25 @@ private void VerifyDirectory(string directory, List expectedFolders) private void VerifyFiles(string directory, List expectedFiles) { string[] files = Directory.GetFiles(directory); - files.Length.ShouldEqual(expectedFiles.Count); IEnumerable expectedFilesWithPath = expectedFiles.Select(x => Path.Combine(directory, x)); Array.Sort(files); files.ShouldMatchInOrder(expectedFilesWithPath); } + + private string SparseSet() + { + StringBuilder sb = new StringBuilder(); + + foreach (string folder in this.currentFolderList) + { + sb.Append(folder.Replace(Path.DirectorySeparatorChar, TestConstants.GitPathSeparator) + .Trim(TestConstants.GitPathSeparator)); + sb.Append("\n"); + } + + ProcessResult result = GitProcess.InvokeProcess(this.Enlistment.RepoRoot, "sparse-checkout set --stdin", sb.ToString()); + + return result.Errors; + } } } diff --git a/Scalar.FunctionalTests/Tests/EnlistmentPerFixture/SymbolicLinkTests.cs b/Scalar.FunctionalTests/Tests/EnlistmentPerFixture/SymbolicLinkTests.cs deleted file mode 100644 index 58defd5f7a..0000000000 --- a/Scalar.FunctionalTests/Tests/EnlistmentPerFixture/SymbolicLinkTests.cs +++ /dev/null @@ -1,194 +0,0 @@ -using NUnit.Framework; -using Scalar.FunctionalTests.FileSystemRunners; -using Scalar.FunctionalTests.Should; -using Scalar.FunctionalTests.Tools; -using Scalar.Tests.Should; -using System.IO; - -namespace Scalar.FunctionalTests.Tests.EnlistmentPerFixture -{ - // MacOnly until issue #297 (add SymLink support for Windows) is complete - [Category(Categories.MacOnly)] - [Category(Categories.NeedsUpdatesForNonVirtualizedMode)] - [TestFixture] - public class SymbolicLinkTests : TestsWithEnlistmentPerFixture - { - private const string TestFolderName = "Test_EPF_SymbolicLinks"; - - // FunctionalTests/20180925_SymLinksPart1 files - private const string TestFileName = "TestFile.txt"; - private const string TestFileContents = "This is a real file"; - private const string TestFile2Name = "TestFile2.txt"; - private const string TestFile2Contents = "This is the second real file"; - private const string ChildFolderName = "ChildDir"; - private const string ChildLinkName = "LinkToFileInFolder"; - private const string GrandChildLinkName = "LinkToFileInParentFolder"; - - // FunctionalTests/20180925_SymLinksPart2 files - // Note: In this branch ChildLinkName has been changed to point to TestFile2Name - private const string GrandChildFileName = "TestFile3.txt"; - private const string GrandChildFileContents = "This is the third file"; - private const string GrandChildLinkNowAFileContents = "This was a link but is now a file"; - - // FunctionalTests/20180925_SymLinksPart3 files - private const string ChildFolder2Name = "ChildDir2"; - - // FunctionalTests/20180925_SymLinksPart4 files - // Note: In this branch ChildLinkName has been changed to a directory and ChildFolder2Name has been changed to a link to ChildFolderName - - private BashRunner bashRunner; - public SymbolicLinkTests() - { - this.bashRunner = new BashRunner(); - } - - [TestCase, Order(1)] - public void CheckoutBranchWithSymLinks() - { - GitHelpers.InvokeGitAgainstScalarRepo(this.Enlistment.RepoRoot, "checkout FunctionalTests/20180925_SymLinksPart1"); - GitHelpers.CheckGitCommandAgainstScalarRepo( - this.Enlistment.RepoRoot, - "status", - "On branch FunctionalTests/20180925_SymLinksPart1", - "nothing to commit, working tree clean"); - - string testFilePath = this.Enlistment.GetSourcePath(Path.Combine(TestFolderName, TestFileName)); - testFilePath.ShouldBeAFile(this.bashRunner).WithContents(TestFileContents); - this.bashRunner.IsSymbolicLink(testFilePath).ShouldBeFalse($"{testFilePath} should not be a symlink"); - - string testFile2Path = this.Enlistment.GetSourcePath(Path.Combine(TestFolderName, TestFile2Name)); - testFile2Path.ShouldBeAFile(this.bashRunner).WithContents(TestFile2Contents); - this.bashRunner.IsSymbolicLink(testFile2Path).ShouldBeFalse($"{testFile2Path} should not be a symlink"); - - string childLinkPath = this.Enlistment.GetSourcePath(Path.Combine(TestFolderName, ChildLinkName)); - this.bashRunner.IsSymbolicLink(childLinkPath).ShouldBeTrue($"{childLinkPath} should be a symlink"); - childLinkPath.ShouldBeAFile(this.bashRunner).WithContents(TestFileContents); - - string grandChildLinkPath = this.Enlistment.GetSourcePath(Path.Combine(TestFolderName, ChildFolderName, GrandChildLinkName)); - this.bashRunner.IsSymbolicLink(grandChildLinkPath).ShouldBeTrue($"{grandChildLinkPath} should be a symlink"); - grandChildLinkPath.ShouldBeAFile(this.bashRunner).WithContents(TestFile2Contents); - } - - [TestCase, Order(2)] - public void CheckoutBranchWhereSymLinksChangeContentsAndTransitionToFile() - { - GitHelpers.InvokeGitAgainstScalarRepo(this.Enlistment.RepoRoot, "checkout FunctionalTests/20180925_SymLinksPart2"); - GitHelpers.CheckGitCommandAgainstScalarRepo( - this.Enlistment.RepoRoot, - "status", - "On branch FunctionalTests/20180925_SymLinksPart2", - "nothing to commit, working tree clean"); - - // testFilePath and testFile2Path are unchanged from FunctionalTests/20180925_SymLinksPart2 - string testFilePath = this.Enlistment.GetSourcePath(Path.Combine(TestFolderName, TestFileName)); - testFilePath.ShouldBeAFile(this.bashRunner).WithContents(TestFileContents); - this.bashRunner.IsSymbolicLink(testFilePath).ShouldBeFalse($"{testFilePath} should not be a symlink"); - - string testFile2Path = this.Enlistment.GetSourcePath(Path.Combine(TestFolderName, TestFile2Name)); - testFile2Path.ShouldBeAFile(this.bashRunner).WithContents(TestFile2Contents); - this.bashRunner.IsSymbolicLink(testFile2Path).ShouldBeFalse($"{testFile2Path} should not be a symlink"); - - // In this branch childLinkPath has been changed to point to testFile2Path - string childLinkPath = this.Enlistment.GetSourcePath(Path.Combine(TestFolderName, ChildLinkName)); - this.bashRunner.IsSymbolicLink(childLinkPath).ShouldBeTrue($"{childLinkPath} should be a symlink"); - childLinkPath.ShouldBeAFile(this.bashRunner).WithContents(TestFile2Contents); - - // grandChildLinkPath should now be a file - string grandChildLinkPath = this.Enlistment.GetSourcePath(Path.Combine(TestFolderName, ChildFolderName, GrandChildLinkName)); - this.bashRunner.IsSymbolicLink(grandChildLinkPath).ShouldBeFalse($"{grandChildLinkPath} should not be a symlink"); - grandChildLinkPath.ShouldBeAFile(this.bashRunner).WithContents(GrandChildLinkNowAFileContents); - - // There should also be a new file in the child folder - string newGrandChildFilePath = this.Enlistment.GetSourcePath(Path.Combine(TestFolderName, ChildFolderName, GrandChildFileName)); - newGrandChildFilePath.ShouldBeAFile(this.bashRunner).WithContents(GrandChildFileContents); - this.bashRunner.IsSymbolicLink(newGrandChildFilePath).ShouldBeFalse($"{newGrandChildFilePath} should not be a symlink"); - } - - [TestCase, Order(3)] - public void CheckoutBranchWhereFilesTransitionToSymLinks() - { - GitHelpers.InvokeGitAgainstScalarRepo(this.Enlistment.RepoRoot, "checkout FunctionalTests/20180925_SymLinksPart3"); - GitHelpers.CheckGitCommandAgainstScalarRepo( - this.Enlistment.RepoRoot, - "status", - "On branch FunctionalTests/20180925_SymLinksPart3", - "nothing to commit, working tree clean"); - - // In this branch testFilePath has been changed to point to newGrandChildFilePath - string testFilePath = this.Enlistment.GetSourcePath(Path.Combine(TestFolderName, TestFileName)); - testFilePath.ShouldBeAFile(this.bashRunner).WithContents(GrandChildFileContents); - this.bashRunner.IsSymbolicLink(testFilePath).ShouldBeTrue($"{testFilePath} should be a symlink"); - - // There should be a new ChildFolder2Name directory - string childFolder2Path = this.Enlistment.GetSourcePath(Path.Combine(TestFolderName, ChildFolder2Name)); - this.bashRunner.IsSymbolicLink(childFolder2Path).ShouldBeFalse($"{childFolder2Path} should not be a symlink"); - childFolder2Path.ShouldBeADirectory(this.bashRunner); - - // The rest of the files are unchanged from FunctionalTests/20180925_SymLinksPart2 - string testFile2Path = this.Enlistment.GetSourcePath(Path.Combine(TestFolderName, TestFile2Name)); - testFile2Path.ShouldBeAFile(this.bashRunner).WithContents(TestFile2Contents); - this.bashRunner.IsSymbolicLink(testFile2Path).ShouldBeFalse($"{testFile2Path} should not be a symlink"); - - string childLinkPath = this.Enlistment.GetSourcePath(Path.Combine(TestFolderName, ChildLinkName)); - this.bashRunner.IsSymbolicLink(childLinkPath).ShouldBeTrue($"{childLinkPath} should be a symlink"); - childLinkPath.ShouldBeAFile(this.bashRunner).WithContents(TestFile2Contents); - - string grandChildLinkPath = this.Enlistment.GetSourcePath(Path.Combine(TestFolderName, ChildFolderName, GrandChildLinkName)); - this.bashRunner.IsSymbolicLink(grandChildLinkPath).ShouldBeFalse($"{grandChildLinkPath} should not be a symlink"); - grandChildLinkPath.ShouldBeAFile(this.bashRunner).WithContents(GrandChildLinkNowAFileContents); - - string newGrandChildFilePath = this.Enlistment.GetSourcePath(Path.Combine(TestFolderName, ChildFolderName, GrandChildFileName)); - newGrandChildFilePath.ShouldBeAFile(this.bashRunner).WithContents(GrandChildFileContents); - this.bashRunner.IsSymbolicLink(newGrandChildFilePath).ShouldBeFalse($"{newGrandChildFilePath} should not be a symlink"); - } - - [TestCase, Order(4)] - public void CheckoutBranchWhereSymLinkTransistionsToFolderAndFolderTransitionsToSymlink() - { - GitHelpers.InvokeGitAgainstScalarRepo(this.Enlistment.RepoRoot, "checkout FunctionalTests/20180925_SymLinksPart4"); - GitHelpers.CheckGitCommandAgainstScalarRepo( - this.Enlistment.RepoRoot, - "status", - "On branch FunctionalTests/20180925_SymLinksPart4", - "nothing to commit, working tree clean"); - - // In this branch ChildLinkName has been changed to a directory and ChildFolder2Name has been changed to a link to ChildFolderName - string linkNowADirectoryPath = this.Enlistment.GetSourcePath(Path.Combine(TestFolderName, ChildLinkName)); - this.bashRunner.IsSymbolicLink(linkNowADirectoryPath).ShouldBeFalse($"{linkNowADirectoryPath} should not be a symlink"); - linkNowADirectoryPath.ShouldBeADirectory(this.bashRunner); - - string directoryNowALinkPath = this.Enlistment.GetSourcePath(Path.Combine(TestFolderName, ChildFolder2Name)); - this.bashRunner.IsSymbolicLink(directoryNowALinkPath).ShouldBeTrue($"{directoryNowALinkPath} should be a symlink"); - } - - [TestCase, Order(5)] - public void GitStatusReportsSymLinkChanges() - { - GitHelpers.CheckGitCommandAgainstScalarRepo( - this.Enlistment.RepoRoot, - "status", - "On branch FunctionalTests/20180925_SymLinksPart4", - "nothing to commit, working tree clean"); - - string testFilePath = this.Enlistment.GetSourcePath(Path.Combine(TestFolderName, TestFileName)); - testFilePath.ShouldBeAFile(this.bashRunner).WithContents(GrandChildFileContents); - this.bashRunner.IsSymbolicLink(testFilePath).ShouldBeTrue($"{testFilePath} should be a symlink"); - - string testFile2Path = this.Enlistment.GetSourcePath(Path.Combine(TestFolderName, TestFile2Name)); - testFile2Path.ShouldBeAFile(this.bashRunner).WithContents(TestFile2Contents); - this.bashRunner.IsSymbolicLink(testFile2Path).ShouldBeFalse($"{testFile2Path} should not be a symlink"); - - // Update testFilePath's symlink to point to testFile2Path - this.bashRunner.CreateSymbolicLink(testFilePath, testFile2Path); - - testFilePath.ShouldBeAFile(this.bashRunner).WithContents(TestFile2Contents); - this.bashRunner.IsSymbolicLink(testFilePath).ShouldBeTrue($"{testFilePath} should be a symlink"); - - GitHelpers.CheckGitCommandAgainstScalarRepo( - this.Enlistment.RepoRoot, - "status", - "On branch FunctionalTests/20180925_SymLinksPart4", - $"modified: {TestFolderName}/{TestFileName}"); - } - } -} diff --git a/Scalar.FunctionalTests/Tests/GitCommands/GitRepoTests.cs b/Scalar.FunctionalTests/Tests/GitCommands/GitRepoTests.cs index 72a5248434..bf543f0e30 100644 --- a/Scalar.FunctionalTests/Tests/GitCommands/GitRepoTests.cs +++ b/Scalar.FunctionalTests/Tests/GitCommands/GitRepoTests.cs @@ -6,6 +6,7 @@ using Scalar.Tests.Should; using System.IO; using System.Linq; +using System.Text; namespace Scalar.FunctionalTests.Tests.GitCommands { @@ -131,8 +132,16 @@ public virtual void SetupForTest() if (this.validateWorkingTree == Settings.ValidateWorkingTreeMode.SparseMode) { - ScalarProcess scalar = new ScalarProcess(this.Enlistment); - scalar.SparseSet(SparseModeFolders); + StringBuilder sb = new StringBuilder(); + + foreach (string folder in SparseModeFolders) + { + sb.Append(folder.Replace(Path.DirectorySeparatorChar, TestConstants.GitPathSeparator) + .Trim(TestConstants.GitPathSeparator)); + sb.Append("\n"); + } + + GitProcess.InvokeProcess(this.Enlistment.RepoRoot, "sparse-checkout set --stdin", sb.ToString()); this.pathPrefixes = SparseModeFolders; } diff --git a/Scalar.FunctionalTests/Tests/MultiEnlistmentTests/SharedCacheTests.cs b/Scalar.FunctionalTests/Tests/MultiEnlistmentTests/SharedCacheTests.cs index ea8cf0d3a8..76739f4708 100644 --- a/Scalar.FunctionalTests/Tests/MultiEnlistmentTests/SharedCacheTests.cs +++ b/Scalar.FunctionalTests/Tests/MultiEnlistmentTests/SharedCacheTests.cs @@ -11,7 +11,6 @@ namespace Scalar.FunctionalTests.Tests.MultiEnlistmentTests { [TestFixture] - [Category(Categories.ExtraCoverage)] public class SharedCacheTests : TestsWithMultiEnlistment { private const string WellKnownFile = "Readme.md"; @@ -256,8 +255,8 @@ private void LoadBlobsViaGit(ScalarFunctionalTestEnlistment enlistment) { // 'git rev-list --objects' will check for all objects' existence, which // triggers an object download on every missing blob. - ProcessResult result = GitHelpers.InvokeGitAgainstScalarRepo(enlistment.RepoRoot, "rev-list --all --objects"); - result.ExitCode.ShouldEqual(0); + ProcessResult result = GitHelpers.InvokeGitAgainstScalarRepo(enlistment.RepoRoot, "rev-list --objects HEAD^{tree}"); + result.ExitCode.ShouldEqual(0, result.Errors); } } } diff --git a/Scalar.FunctionalTests/Tools/ScalarProcess.cs b/Scalar.FunctionalTests/Tools/ScalarProcess.cs index 2f5dc60fc9..b820ce1f49 100644 --- a/Scalar.FunctionalTests/Tools/ScalarProcess.cs +++ b/Scalar.FunctionalTests/Tools/ScalarProcess.cs @@ -1,8 +1,6 @@ using Scalar.Tests.Should; -using System.Collections.Generic; using System.Diagnostics; using System.IO; -using System.Text; namespace Scalar.FunctionalTests.Tools { @@ -63,20 +61,6 @@ public string Prefetch(string args, bool failOnError, string standardInput = nul return this.CallScalar("prefetch \"" + this.enlistmentRoot + "\" " + args, failOnError ? SuccessExitCode : DoNotCheckExitCode, standardInput: standardInput); } - public string SparseSet(IEnumerable folders) - { - StringBuilder sb = new StringBuilder(); - - foreach (string folder in folders) - { - sb.Append(folder.Replace(Path.DirectorySeparatorChar, TestConstants.GitPathSeparator) - .Trim(TestConstants.GitPathSeparator)); - sb.Append("\n"); - } - - return this.CallScalar("sparse --set-stdin \"" + this.enlistmentRoot + "\" ", SuccessExitCode, standardInput: sb.ToString()); - } - public void Repair(bool confirm) { string confirmArg = confirm ? "--confirm " : string.Empty; diff --git a/Scalar.Installer.Windows/Setup.iss b/Scalar.Installer.Windows/Setup.iss index 6cf2af9088..f6860b0416 100644 --- a/Scalar.Installer.Windows/Setup.iss +++ b/Scalar.Installer.Windows/Setup.iss @@ -9,7 +9,6 @@ #define ServiceDir BuildOutputDir + "\Scalar.Service.Windows\bin\" + PlatformAndConfiguration #define ServiceUIDir BuildOutputDir + "\Scalar.Service.UI\bin\" + PlatformAndConfiguration #define ScalarMountDir BuildOutputDir + "\Scalar.Mount.Windows\bin\" + PlatformAndConfiguration -#define ReadObjectDir BuildOutputDir + "\Scalar.ReadObjectHook.Windows\bin\" + PlatformAndConfiguration #define ScalarUpgraderDir BuildOutputDir + "\Scalar.Upgrader\bin\" + PlatformAndConfiguration + "\net461" #define MyAppName "Scalar" @@ -78,10 +77,6 @@ DestDir: "{app}"; Flags: ignoreversion; Source:"{#ScalarUpgraderDir}\Scalar.Upgr DestDir: "{app}"; Flags: ignoreversion; Source:"{#ScalarUpgraderDir}\Scalar.Upgrader.exe" DestDir: "{app}"; Flags: ignoreversion; Source:"{#ScalarUpgraderDir}\Scalar.Upgrader.exe.config" -; Scalar.ReadObjectHook files -DestDir: "{app}"; Flags: ignoreversion; Source:"{#ReadObjectDir}\Scalar.ReadObjectHook.pdb" -DestDir: "{app}"; Flags: ignoreversion; Source:"{#ReadObjectDir}\Scalar.ReadObjectHook.exe" - ; Cpp Dependencies DestDir: "{app}"; Flags: ignoreversion; Source:"{#VCRuntimeDir}\msvcp140.dll" DestDir: "{app}"; Flags: ignoreversion; Source:"{#VCRuntimeDir}\msvcp140_1.dll" diff --git a/Scalar.Mount/InProcessMount.cs b/Scalar.Mount/InProcessMount.cs index 59412f9aea..17847192e1 100644 --- a/Scalar.Mount/InProcessMount.cs +++ b/Scalar.Mount/InProcessMount.cs @@ -99,12 +99,6 @@ public void Mount(EventLevel verbosity, Keywords keywords) this.ValidateMountPoints(); - string errorMessage; - if (!HooksInstaller.TryUpdateHooks(this.context, out errorMessage)) - { - this.FailMountAndExit(errorMessage); - } - ScalarPlatform.Instance.ConfigureVisualStudio(this.enlistment.GitBinPath, this.tracer); this.MountAndStartWorkingDirectoryCallbacks(this.cacheServer); diff --git a/Scalar.Mount/Scalar.Mount.Windows.csproj b/Scalar.Mount/Scalar.Mount.Windows.csproj index 23d26bf165..955d04fa32 100644 --- a/Scalar.Mount/Scalar.Mount.Windows.csproj +++ b/Scalar.Mount/Scalar.Mount.Windows.csproj @@ -108,7 +108,6 @@ - xcopy /Y $(BuildOutputDir)\Scalar.ReadObjectHook.Windows\bin\$(Platform)\$(Configuration)\Scalar.ReadObjectHook.* $(TargetDir) diff --git a/Scalar.Native.Mac/Scalar.Native.Mac.xcworkspace/contents.xcworkspacedata b/Scalar.Native.Mac/Scalar.Native.Mac.xcworkspace/contents.xcworkspacedata deleted file mode 100644 index 8074b547d8..0000000000 --- a/Scalar.Native.Mac/Scalar.Native.Mac.xcworkspace/contents.xcworkspacedata +++ /dev/null @@ -1,7 +0,0 @@ - - - - - diff --git a/Scalar.Native.Mac/Scalar.Native.Mac.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist b/Scalar.Native.Mac/Scalar.Native.Mac.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist deleted file mode 100644 index 18d981003d..0000000000 --- a/Scalar.Native.Mac/Scalar.Native.Mac.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist +++ /dev/null @@ -1,8 +0,0 @@ - - - - - IDEDidComputeMac32BitWarning - - - diff --git a/Scalar.Native.Mac/Scalar.Native.Mac.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings b/Scalar.Native.Mac/Scalar.Native.Mac.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings deleted file mode 100644 index 08de0be8d3..0000000000 --- a/Scalar.Native.Mac/Scalar.Native.Mac.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings +++ /dev/null @@ -1,8 +0,0 @@ - - - - - IDEWorkspaceSharedSettings_AutocreateContextsIfNeeded - - - diff --git a/Scalar.Native.Mac/Scalar.Native.Mac.xcworkspace/xcshareddata/xcschemes/Scalar.Native.Mac.xcscheme b/Scalar.Native.Mac/Scalar.Native.Mac.xcworkspace/xcshareddata/xcschemes/Scalar.Native.Mac.xcscheme deleted file mode 100644 index 4230eb6a52..0000000000 --- a/Scalar.Native.Mac/Scalar.Native.Mac.xcworkspace/xcshareddata/xcschemes/Scalar.Native.Mac.xcscheme +++ /dev/null @@ -1,32 +0,0 @@ - - - - - - - - - - - - - - - diff --git a/Scalar.NativeHooks.Common/common.h b/Scalar.NativeHooks.Common/common.h deleted file mode 100644 index 2e7960ddb0..0000000000 --- a/Scalar.NativeHooks.Common/common.h +++ /dev/null @@ -1,65 +0,0 @@ -#pragma once - -#include - -#ifdef __APPLE__ -typedef std::string PATH_STRING; -typedef int PIPE_HANDLE; -#define PRINTF_FMT(X, Y) __attribute__((__format__ (printf, X, Y))) -#elif _WIN32 -typedef std::wstring PATH_STRING; -typedef HANDLE PIPE_HANDLE; -#define PRINTF_FMT(X, Y) -#else -#error Unsupported platform -#endif - -#if __cplusplus < 201103L - #error The hooks require at least C++11 support -#endif - -enum ReturnCode -{ - Success = 0, - InvalidArgCount = 1, - GetCurrentDirectoryFailure = 2, - NotInScalarEnlistment = 3, - PipeConnectError = 4, - PipeConnectTimeout = 5, - InvalidSHA = 6, - PipeWriteFailed = 7, - PipeReadFailed = 8, - FailureToDownload = 9, - PathNameError = 10, - - LastError = PathNameError, -}; - -void die(int err, const char *fmt, ...) PRINTF_FMT(2,3); -inline void die(int err, const char *fmt, ...) -{ - va_list params; - va_start(params, fmt); - vfprintf(stderr, fmt, params); - va_end(params); - exit(err); -} - -PATH_STRING GetFinalPathName(const PATH_STRING& path); -PATH_STRING GetScalarPipeName(const char *appName); -PIPE_HANDLE CreatePipeToScalar(const PATH_STRING& pipeName); -void DisableCRLFTranslationOnStdPipes(); - -bool WriteToPipe( - PIPE_HANDLE pipe, - const char* message, - unsigned long messageLength, - /* out */ unsigned long* bytesWritten, - /* out */ int* error); - -bool ReadFromPipe( - PIPE_HANDLE pipe, - char* buffer, - unsigned long bufferLength, - /* out */ unsigned long* bytesRead, - /* out */ int* error); diff --git a/Scalar.NativeHooks.Common/common.posix.cpp b/Scalar.NativeHooks.Common/common.posix.cpp deleted file mode 100644 index 58a8badd39..0000000000 --- a/Scalar.NativeHooks.Common/common.posix.cpp +++ /dev/null @@ -1,194 +0,0 @@ -#include "stdafx.h" - -#include -#include -#include -#include -#include -#include - -#include "common.h" - -#define MAX_PATH 260 - -PATH_STRING GetFinalPathName(const PATH_STRING& path) -{ - // TODO(#1358): Implement - return path; -} - -PATH_STRING GetScalarPipeName(const char *appName) -{ - // The pipe name is built using the path of the Scalar enlistment root. - // Start in the current directory and walk up the directory tree - // until we find a folder that contains the ".scalar" folder - - // TODO 640838: Support paths longer than MAX_PATH - char enlistmentRoot[MAX_PATH]; - if (getcwd(enlistmentRoot, MAX_PATH) == nullptr) - { - die(ReturnCode::GetCurrentDirectoryFailure, "getcwd failed (%d)\n", errno); - } - - PATH_STRING finalRootPath(GetFinalPathName(enlistmentRoot)); - size_t enlistmentRootLength = finalRootPath.length(); - // allow an extra byte in case we need to add a trailing slash - if (enlistmentRootLength + 2 > sizeof(enlistmentRoot)) - { - die(ReturnCode::PipeConnectError, - "Could not copy finalRootPath: %s, insufficient buffer. enlistmentRootLength: %zu, sizeof(enlistmentRoot): %zu\n", - finalRootPath.c_str(), - enlistmentRootLength, - sizeof(enlistmentRoot)); - } - - memcpy(enlistmentRoot, finalRootPath.c_str(), enlistmentRootLength); - if (enlistmentRootLength == 0 || enlistmentRoot[enlistmentRootLength - 1] != '/') - { - enlistmentRoot[enlistmentRootLength++] = '/'; - } - enlistmentRoot[enlistmentRootLength] = '\0'; - - // Walk up enlistmentRoot looking for a folder named .scalar - char* lastslash = enlistmentRoot + enlistmentRootLength - 1; - bool scalarFound = false; - while (1) - { - *lastslash = '\0'; - DIR* directory = opendir(enlistmentRoot); - if (directory == nullptr) - { - die(ReturnCode::NotInScalarEnlistment, "Failed to open directory: %s, error: %d\n", enlistmentRoot, errno); - } - - dirent* dirEntry = readdir(directory); - while (!scalarFound && dirEntry != nullptr) - { - if (dirEntry->d_type == DT_DIR && strcmp(dirEntry->d_name, ".scalar") == 0) - { - scalarFound = true; - } - else - { - dirEntry = readdir(directory); - } - } - - closedir(directory); - - if (scalarFound) - { - break; - } - - if (errno != 0) - { - die(ReturnCode::NotInScalarEnlistment, "readdir failed in directory: %s, error: %i\n", enlistmentRoot, errno); - } - - lastslash--; - while ((enlistmentRoot != lastslash) && (*lastslash != '/')) - { - lastslash--; - } - - if (enlistmentRoot == lastslash) - { - die(ReturnCode::NotInScalarEnlistment, "%s must be run from inside a Scalar enlistment\n", appName); - } - - *(lastslash + 1) = 0; - }; - - *(lastslash) = 0; - - return PATH_STRING(enlistmentRoot) + "/.scalar/Scalar_NetCorePipe"; -} - -PIPE_HANDLE CreatePipeToScalar(const PATH_STRING& pipeName) -{ - PIPE_HANDLE socket_fd = socket(PF_UNIX, SOCK_STREAM, 0); - if (socket_fd < 0) - { - die(ReturnCode::PipeConnectError, "Failed to create a new socket, pipeName: %s, error: %d\n", pipeName.c_str(), errno); - } - - struct sockaddr_un socket_address; - memset(&socket_address, 0, sizeof(struct sockaddr_un)); - - socket_address.sun_family = AF_UNIX; - size_t pathLength = pipeName.length(); - if (pathLength + 1 > sizeof(socket_address.sun_path)) - { - die(ReturnCode::PipeConnectError, - "Could not copy pipeName: %s, insufficient buffer. pathLength: %zu, sizeof(socket_address.sun_path): %zu\n", - pipeName.c_str(), - pathLength, - sizeof(socket_address.sun_path)); - } - - memcpy(socket_address.sun_path, pipeName.c_str(), pathLength); - socket_address.sun_path[pathLength] = '\0'; - - if(connect(socket_fd, (struct sockaddr *) &socket_address, sizeof(struct sockaddr_un)) != 0) - { - die(ReturnCode::PipeConnectError, "Failed to connect socket, pipeName: %s, error: %d\n", pipeName.c_str(), errno); - } - - return socket_fd; -} - -void DisableCRLFTranslationOnStdPipes() -{ - // not required on Mac -} - -bool WriteToPipe(PIPE_HANDLE pipe, const char* message, size_t messageLength, /* out */ size_t* bytesWritten, /* out */ int* error) -{ - - size_t bytesRemaining = messageLength; - while (bytesRemaining > 0) - { - size_t offset = messageLength - bytesRemaining; - ssize_t bytesSent = write(pipe, message + offset, bytesRemaining); - - if (-1 == bytesSent) - { - if (EINTR != errno) - { - break; - } - } - else - { - bytesRemaining -= bytesSent; - } - } - - *bytesWritten = messageLength - bytesRemaining; - - bool success = *bytesWritten == messageLength; - *error = success ? 0 : errno; - return success; -} - -bool ReadFromPipe(PIPE_HANDLE pipe, char* buffer, size_t bufferLength, /* out */ size_t* bytesRead, /* out */ int* error) -{ - *error = 0; - *bytesRead = 0; - ssize_t readByteCount; - - do - { - readByteCount = recv(pipe, buffer, bufferLength, 0); - } while (readByteCount == -1 && errno == EINTR); - - if (readByteCount < 0) - { - *error = errno; - return false; - } - - *bytesRead = readByteCount; - return true; -} diff --git a/Scalar.NativeHooks.Common/common.windows.cpp b/Scalar.NativeHooks.Common/common.windows.cpp deleted file mode 100644 index 6d049709b5..0000000000 --- a/Scalar.NativeHooks.Common/common.windows.cpp +++ /dev/null @@ -1,195 +0,0 @@ -#pragma once -#include "stdafx.h" -#include -#include -#include -#include "common.h" - -PATH_STRING GetFinalPathName(const PATH_STRING& path) -{ - HANDLE fileHandle; - - // Using FILE_FLAG_BACKUP_SEMANTICS as it works with file as well as folder path - // According to MSDN, https://msdn.microsoft.com/en-us/library/windows/desktop/aa363858(v=vs.85).aspx, - // we must set this flag to obtain a handle to a directory - fileHandle = CreateFileW( - path.c_str(), - FILE_READ_ATTRIBUTES, - FILE_SHARE_READ | FILE_SHARE_WRITE, - NULL, - OPEN_EXISTING, - FILE_FLAG_BACKUP_SEMANTICS, - NULL); - - if (fileHandle == INVALID_HANDLE_VALUE) - { - die(ReturnCode::PathNameError, "Could not open oppen handle to %ls to determine final path name, Error: %d\n", path.c_str(), GetLastError()); - } - - wchar_t finalPathByHandle[MAX_PATH] = { 0 }; - DWORD finalPathSize = GetFinalPathNameByHandleW(fileHandle, finalPathByHandle, MAX_PATH, FILE_NAME_NORMALIZED); - if (finalPathSize == 0) - { - die(ReturnCode::PathNameError, "Could not get final path name by handle for %ls, Error: %d\n", path.c_str(), GetLastError()); - } - - std::wstring finalPath(finalPathByHandle); - - // The remarks section of GetFinalPathNameByHandle mentions the return being prefixed with "\\?\" or "\\?\UNC\" - // More information the prefixes is here http://msdn.microsoft.com/en-us/library/aa365247(v=VS.85).aspx - std::wstring PathPrefix(L"\\\\?\\"); - std::wstring UncPrefix(L"\\\\?\\UNC\\"); - - if (finalPath.compare(0, UncPrefix.length(), UncPrefix) == 0) - { - finalPath = L"\\\\" + finalPath.substr(UncPrefix.length()); - } - else if (finalPath.compare(0, PathPrefix.length(), PathPrefix) == 0) - { - finalPath = finalPath.substr(PathPrefix.length()); - } - - return finalPath; -} - -PATH_STRING GetScalarPipeName(const char *appName) -{ - // The pipe name is built using the path of the Scalar enlistment root. - // Start in the current directory and walk up the directory tree - // until we find a folder that contains the ".scalar" folder - - const size_t dotScalarRelativePathLength = sizeof(L"\\.scalar") / sizeof(wchar_t); - - // TODO 640838: Support paths longer than MAX_PATH - wchar_t enlistmentRoot[MAX_PATH]; - DWORD currentDirResult = GetCurrentDirectoryW(MAX_PATH - dotScalarRelativePathLength, enlistmentRoot); - if (currentDirResult == 0 || currentDirResult > MAX_PATH - dotScalarRelativePathLength) - { - die(ReturnCode::GetCurrentDirectoryFailure, "GetCurrentDirectory failed (%d)\n", GetLastError()); - } - - PATH_STRING finalRootPath(GetFinalPathName(enlistmentRoot)); - errno_t copyResult = wcscpy_s(enlistmentRoot, finalRootPath.c_str()); - if (copyResult != 0) - { - die(ReturnCode::PipeConnectError, "Could not copy finalRootPath: %ls. Error: %d\n", finalRootPath.c_str(), copyResult); - } - - size_t enlistmentRootLength = wcslen(enlistmentRoot); - if ('\\' != enlistmentRoot[enlistmentRootLength - 1]) - { - wcscat_s(enlistmentRoot, L"\\"); - enlistmentRootLength++; - } - - // Walk up enlistmentRoot looking for a folder named .scalar - wchar_t* lastslash = enlistmentRoot + enlistmentRootLength - 1; - WIN32_FIND_DATAW findFileData; - HANDLE dotScalarHandle; - while (1) - { - wcscat_s(lastslash, MAX_PATH - (lastslash - enlistmentRoot), L".scalar"); - dotScalarHandle = FindFirstFileW(enlistmentRoot, &findFileData); - if (dotScalarHandle != INVALID_HANDLE_VALUE) - { - FindClose(dotScalarHandle); - if (findFileData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) - { - break; - } - } - - lastslash--; - while ((enlistmentRoot != lastslash) && (*lastslash != '\\')) - { - lastslash--; - } - - if (enlistmentRoot == lastslash) - { - die(ReturnCode::NotInScalarEnlistment, "%s must be run from inside a Scalar enlistment\n", appName); - } - - *(lastslash + 1) = 0; - }; - - *(lastslash) = 0; - - PATH_STRING namedPipe(CharUpperW(enlistmentRoot)); - std::replace(namedPipe.begin(), namedPipe.end(), L':', L'_'); - return L"\\\\.\\pipe\\Scalar_" + namedPipe; -} - -PIPE_HANDLE CreatePipeToScalar(const PATH_STRING& pipeName) -{ - PIPE_HANDLE pipeHandle; - while (1) - { - pipeHandle = CreateFileW( - pipeName.c_str(), // pipe name - GENERIC_READ | // read and write access - GENERIC_WRITE, - 0, // no sharing - NULL, // default security attributes - OPEN_EXISTING, // opens existing pipe - 0, // default attributes - NULL); // no template file - - if (pipeHandle != INVALID_HANDLE_VALUE) - { - break; - } - - if (GetLastError() != ERROR_PIPE_BUSY) - { - die(ReturnCode::PipeConnectError, "Could not open pipe: %ls, Error: %d\n", pipeName.c_str(), GetLastError()); - } - - if (!WaitNamedPipeW(pipeName.c_str(), 3000)) - { - die(ReturnCode::PipeConnectTimeout, "Could not open pipe: %ls, Timed out.", pipeName.c_str()); - } - } - - return pipeHandle; -} - -void DisableCRLFTranslationOnStdPipes() -{ - // set the mode to binary so we don't get CRLF translation - _setmode(_fileno(stdin), _O_BINARY); - _setmode(_fileno(stdout), _O_BINARY); -} - -bool WriteToPipe(PIPE_HANDLE pipe, const char* message, unsigned long messageLength, /* out */ unsigned long* bytesWritten, /* out */ int* error) -{ - BOOL success = WriteFile( - pipe, // pipe handle - message, // message - messageLength, // message length - bytesWritten, // bytes written - NULL); // not overlapped - - *error = success ? 0 : GetLastError(); - - return success != FALSE; -} - -bool ReadFromPipe(PIPE_HANDLE pipe, char* buffer, unsigned long bufferLength, /* out */ unsigned long* bytesRead, /* out */ int* error) -{ - *error = 0; - *bytesRead = 0; - BOOL success = ReadFile( - pipe, // pipe handle - buffer, // buffer to receive reply - bufferLength, // size of buffer - bytesRead, // number of bytes read - NULL); // not overlapped - - if (!success) - { - *error = GetLastError(); - } - - return success || (*error == ERROR_MORE_DATA); -} diff --git a/Scalar.ReadObjectHook/Scalar.ReadObjectHook.Mac.xcodeproj/project.pbxproj b/Scalar.ReadObjectHook/Scalar.ReadObjectHook.Mac.xcodeproj/project.pbxproj deleted file mode 100644 index 2d856adfde..0000000000 --- a/Scalar.ReadObjectHook/Scalar.ReadObjectHook.Mac.xcodeproj/project.pbxproj +++ /dev/null @@ -1,286 +0,0 @@ -// !$*UTF8*$! -{ - archiveVersion = 1; - classes = { - }; - objectVersion = 50; - objects = { - -/* Begin PBXBuildFile section */ - 2673FD9620EBDAA900B64B7F /* main.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 2673FD9520EBDAA900B64B7F /* main.cpp */; }; - 2673FD9C20EBDEA500B64B7F /* packet.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 2673FD9B20EBDEA500B64B7F /* packet.cpp */; }; - 26E839D820FD387D004E53CE /* common.posix.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 26E839D720FD29EC004E53CE /* common.posix.cpp */; }; -/* End PBXBuildFile section */ - -/* Begin PBXCopyFilesBuildPhase section */ - 2673FD9020EBDAA900B64B7F /* CopyFiles */ = { - isa = PBXCopyFilesBuildPhase; - buildActionMask = 2147483647; - dstPath = /usr/share/man/man1/; - dstSubfolderSpec = 0; - files = ( - ); - runOnlyForDeploymentPostprocessing = 1; - }; -/* End PBXCopyFilesBuildPhase section */ - -/* Begin PBXFileReference section */ - 2673FD9220EBDAA900B64B7F /* Scalar.ReadObjectHook */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = Scalar.ReadObjectHook; sourceTree = BUILT_PRODUCTS_DIR; }; - 2673FD9520EBDAA900B64B7F /* main.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = main.cpp; sourceTree = SOURCE_ROOT; }; - 2673FD9A20EBDEA500B64B7F /* packet.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = packet.h; sourceTree = SOURCE_ROOT; }; - 2673FD9B20EBDEA500B64B7F /* packet.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = packet.cpp; sourceTree = SOURCE_ROOT; }; - 2673FD9D20EBDEAA00B64B7F /* common.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = common.h; path = ../Scalar.NativeHooks.Common/common.h; sourceTree = SOURCE_ROOT; }; - 26E839D720FD29EC004E53CE /* common.posix.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = common.posix.cpp; path = ../Scalar.NativeHooks.Common/common.posix.cpp; sourceTree = SOURCE_ROOT; }; - 26E839DA20FD58B8004E53CE /* stdafx.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = stdafx.h; sourceTree = SOURCE_ROOT; }; -/* End PBXFileReference section */ - -/* Begin PBXFrameworksBuildPhase section */ - 2673FD8F20EBDAA900B64B7F /* Frameworks */ = { - isa = PBXFrameworksBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - runOnlyForDeploymentPostprocessing = 0; - }; -/* End PBXFrameworksBuildPhase section */ - -/* Begin PBXGroup section */ - 2673FD7F20EBD81D00B64B7F = { - isa = PBXGroup; - children = ( - 26E839DA20FD58B8004E53CE /* stdafx.h */, - 26E839D720FD29EC004E53CE /* common.posix.cpp */, - 2673FD9D20EBDEAA00B64B7F /* common.h */, - 2673FD9B20EBDEA500B64B7F /* packet.cpp */, - 2673FD9A20EBDEA500B64B7F /* packet.h */, - 2673FD9520EBDAA900B64B7F /* main.cpp */, - 2673FD9320EBDAA900B64B7F /* Products */, - ); - sourceTree = ""; - }; - 2673FD9320EBDAA900B64B7F /* Products */ = { - isa = PBXGroup; - children = ( - 2673FD9220EBDAA900B64B7F /* Scalar.ReadObjectHook */, - ); - name = Products; - sourceTree = ""; - }; -/* End PBXGroup section */ - -/* Begin PBXNativeTarget section */ - 2673FD9120EBDAA900B64B7F /* Scalar.ReadObjectHook */ = { - isa = PBXNativeTarget; - buildConfigurationList = 2673FD9720EBDAA900B64B7F /* Build configuration list for PBXNativeTarget "Scalar.ReadObjectHook" */; - buildPhases = ( - 2673FD8E20EBDAA900B64B7F /* Sources */, - 2673FD8F20EBDAA900B64B7F /* Frameworks */, - 2673FD9020EBDAA900B64B7F /* CopyFiles */, - ); - buildRules = ( - ); - dependencies = ( - ); - name = Scalar.ReadObjectHook; - productName = Scalar.ReadObjectHook; - productReference = 2673FD9220EBDAA900B64B7F /* Scalar.ReadObjectHook */; - productType = "com.apple.product-type.tool"; - }; -/* End PBXNativeTarget section */ - -/* Begin PBXProject section */ - 2673FD8020EBD81D00B64B7F /* Project object */ = { - isa = PBXProject; - attributes = { - LastUpgradeCheck = 0940; - TargetAttributes = { - 2673FD9120EBDAA900B64B7F = { - CreatedOnToolsVersion = 9.4.1; - }; - }; - }; - buildConfigurationList = 2673FD8320EBD81D00B64B7F /* Build configuration list for PBXProject "Scalar.ReadObjectHook.Mac" */; - compatibilityVersion = "Xcode 9.3"; - developmentRegion = en; - hasScannedForEncodings = 0; - knownRegions = ( - en, - ); - mainGroup = 2673FD7F20EBD81D00B64B7F; - productRefGroup = 2673FD9320EBDAA900B64B7F /* Products */; - projectDirPath = ""; - projectRoot = ""; - targets = ( - 2673FD9120EBDAA900B64B7F /* Scalar.ReadObjectHook */, - ); - }; -/* End PBXProject section */ - -/* Begin PBXSourcesBuildPhase section */ - 2673FD8E20EBDAA900B64B7F /* Sources */ = { - isa = PBXSourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - 26E839D820FD387D004E53CE /* common.posix.cpp in Sources */, - 2673FD9620EBDAA900B64B7F /* main.cpp in Sources */, - 2673FD9C20EBDEA500B64B7F /* packet.cpp in Sources */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; -/* End PBXSourcesBuildPhase section */ - -/* Begin XCBuildConfiguration section */ - 2673FD8420EBD81D00B64B7F /* Debug */ = { - isa = XCBuildConfiguration; - buildSettings = { - }; - name = Debug; - }; - 2673FD8520EBD81D00B64B7F /* Release */ = { - isa = XCBuildConfiguration; - buildSettings = { - }; - name = Release; - }; - 2673FD9820EBDAA900B64B7F /* Debug */ = { - isa = XCBuildConfiguration; - buildSettings = { - ALWAYS_SEARCH_USER_PATHS = NO; - CLANG_ANALYZER_NONNULL = YES; - CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; - CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; - CLANG_CXX_LIBRARY = "libc++"; - CLANG_ENABLE_MODULES = YES; - CLANG_ENABLE_OBJC_ARC = YES; - CLANG_ENABLE_OBJC_WEAK = YES; - CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; - CLANG_WARN_BOOL_CONVERSION = YES; - CLANG_WARN_COMMA = YES; - CLANG_WARN_CONSTANT_CONVERSION = YES; - CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; - CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; - CLANG_WARN_DOCUMENTATION_COMMENTS = YES; - CLANG_WARN_EMPTY_BODY = YES; - CLANG_WARN_ENUM_CONVERSION = YES; - CLANG_WARN_INFINITE_RECURSION = YES; - CLANG_WARN_INT_CONVERSION = YES; - CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; - CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; - CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; - CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; - CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; - CLANG_WARN_STRICT_PROTOTYPES = YES; - CLANG_WARN_SUSPICIOUS_MOVE = YES; - CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; - CLANG_WARN_UNREACHABLE_CODE = YES; - CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; - CODE_SIGN_IDENTITY = "Mac Developer"; - CODE_SIGN_STYLE = Automatic; - COPY_PHASE_STRIP = NO; - DEBUG_INFORMATION_FORMAT = dwarf; - DEVELOPMENT_TEAM = UBF8T346G9; - ENABLE_STRICT_OBJC_MSGSEND = YES; - ENABLE_TESTABILITY = YES; - GCC_C_LANGUAGE_STANDARD = gnu11; - GCC_DYNAMIC_NO_PIC = NO; - GCC_NO_COMMON_BLOCKS = YES; - GCC_OPTIMIZATION_LEVEL = 0; - GCC_PREPROCESSOR_DEFINITIONS = ( - "DEBUG=1", - "$(inherited)", - ); - GCC_TREAT_WARNINGS_AS_ERRORS = YES; - GCC_WARN_64_TO_32_BIT_CONVERSION = YES; - GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; - GCC_WARN_UNDECLARED_SELECTOR = YES; - GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; - GCC_WARN_UNUSED_FUNCTION = YES; - GCC_WARN_UNUSED_VARIABLE = YES; - MACOSX_DEPLOYMENT_TARGET = 10.13; - MTL_ENABLE_DEBUG_INFO = YES; - ONLY_ACTIVE_ARCH = YES; - PRODUCT_NAME = "$(TARGET_NAME)"; - SDKROOT = macosx; - }; - name = Debug; - }; - 2673FD9920EBDAA900B64B7F /* Release */ = { - isa = XCBuildConfiguration; - buildSettings = { - ALWAYS_SEARCH_USER_PATHS = NO; - CLANG_ANALYZER_NONNULL = YES; - CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; - CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; - CLANG_CXX_LIBRARY = "libc++"; - CLANG_ENABLE_MODULES = YES; - CLANG_ENABLE_OBJC_ARC = YES; - CLANG_ENABLE_OBJC_WEAK = YES; - CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; - CLANG_WARN_BOOL_CONVERSION = YES; - CLANG_WARN_COMMA = YES; - CLANG_WARN_CONSTANT_CONVERSION = YES; - CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; - CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; - CLANG_WARN_DOCUMENTATION_COMMENTS = YES; - CLANG_WARN_EMPTY_BODY = YES; - CLANG_WARN_ENUM_CONVERSION = YES; - CLANG_WARN_INFINITE_RECURSION = YES; - CLANG_WARN_INT_CONVERSION = YES; - CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; - CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; - CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; - CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; - CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; - CLANG_WARN_STRICT_PROTOTYPES = YES; - CLANG_WARN_SUSPICIOUS_MOVE = YES; - CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; - CLANG_WARN_UNREACHABLE_CODE = YES; - CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; - CODE_SIGN_IDENTITY = "Mac Developer"; - CODE_SIGN_STYLE = Automatic; - COPY_PHASE_STRIP = NO; - DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; - DEVELOPMENT_TEAM = UBF8T346G9; - ENABLE_NS_ASSERTIONS = NO; - ENABLE_STRICT_OBJC_MSGSEND = YES; - GCC_C_LANGUAGE_STANDARD = gnu11; - GCC_NO_COMMON_BLOCKS = YES; - GCC_TREAT_WARNINGS_AS_ERRORS = YES; - GCC_WARN_64_TO_32_BIT_CONVERSION = YES; - GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; - GCC_WARN_UNDECLARED_SELECTOR = YES; - GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; - GCC_WARN_UNUSED_FUNCTION = YES; - GCC_WARN_UNUSED_VARIABLE = YES; - MACOSX_DEPLOYMENT_TARGET = 10.13; - MTL_ENABLE_DEBUG_INFO = NO; - PRODUCT_NAME = "$(TARGET_NAME)"; - SDKROOT = macosx; - }; - name = Release; - }; -/* End XCBuildConfiguration section */ - -/* Begin XCConfigurationList section */ - 2673FD8320EBD81D00B64B7F /* Build configuration list for PBXProject "Scalar.ReadObjectHook.Mac" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - 2673FD8420EBD81D00B64B7F /* Debug */, - 2673FD8520EBD81D00B64B7F /* Release */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; - }; - 2673FD9720EBDAA900B64B7F /* Build configuration list for PBXNativeTarget "Scalar.ReadObjectHook" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - 2673FD9820EBDAA900B64B7F /* Debug */, - 2673FD9920EBDAA900B64B7F /* Release */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; - }; -/* End XCConfigurationList section */ - }; - rootObject = 2673FD8020EBD81D00B64B7F /* Project object */; -} diff --git a/Scalar.ReadObjectHook/Scalar.ReadObjectHook.Mac.xcodeproj/project.xcworkspace/contents.xcworkspacedata b/Scalar.ReadObjectHook/Scalar.ReadObjectHook.Mac.xcodeproj/project.xcworkspace/contents.xcworkspacedata deleted file mode 100644 index e1907900c2..0000000000 --- a/Scalar.ReadObjectHook/Scalar.ReadObjectHook.Mac.xcodeproj/project.xcworkspace/contents.xcworkspacedata +++ /dev/null @@ -1,7 +0,0 @@ - - - - - diff --git a/Scalar.ReadObjectHook/Scalar.ReadObjectHook.Mac.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist b/Scalar.ReadObjectHook/Scalar.ReadObjectHook.Mac.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist deleted file mode 100644 index 18d981003d..0000000000 --- a/Scalar.ReadObjectHook/Scalar.ReadObjectHook.Mac.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist +++ /dev/null @@ -1,8 +0,0 @@ - - - - - IDEDidComputeMac32BitWarning - - - diff --git a/Scalar.ReadObjectHook/Scalar.ReadObjectHook.Windows.vcxproj b/Scalar.ReadObjectHook/Scalar.ReadObjectHook.Windows.vcxproj deleted file mode 100644 index 10f556be6d..0000000000 --- a/Scalar.ReadObjectHook/Scalar.ReadObjectHook.Windows.vcxproj +++ /dev/null @@ -1,130 +0,0 @@ - - - - - Debug - x64 - - - Release - x64 - - - - {5A6656D5-81C7-472C-9DC8-32D071CB2258} - Win32Proj - readobject - 10.0.17763.0 - Scalar.ReadObjectHook.Windows - Scalar.ReadObjectHook - - - - - Application - true - v141 - MultiByte - - - Application - false - v141 - true - MultiByte - - - - - - - - - - - - - - - true - - - false - - - - Use - Level4 - Disabled - _DEBUG;_CONSOLE;%(PreprocessorDefinitions) - true - true - C:\Program Files (x86)\Windows Kits\10\Include\10.0.10240.0\ucrt;$(SolutionDir)\Scalar.NativeHooks.Common;%(AdditionalIncludeDirectories) - /Zc:__cplusplus - - - Console - true - C:\Program Files (x86)\Windows Kits\10\Lib\10.0.10240.0\ucrt\x64;%(AdditionalLibraryDirectories) - - - $(BuildOutputDir)\$(ProjectName)\intermediate\$(Platform)\$(Configuration)\$(MSBuildProjectName).log - - - - - $(BuildOutputDir) - - - - - Level4 - Use - MaxSpeed - true - true - NDEBUG;_CONSOLE;%(PreprocessorDefinitions) - true - true - C:\Program Files (x86)\Windows Kits\10\Include\10.0.10240.0\ucrt;$(SolutionDir)\Scalar.NativeHooks.Common;%(AdditionalIncludeDirectories) - /Zc:__cplusplus - - - Console - true - true - true - C:\Program Files (x86)\Windows Kits\10\Lib\10.0.10240.0\ucrt\x64;%(AdditionalLibraryDirectories) - - - $(BuildOutputDir)\$(ProjectName)\intermediate\$(Platform)\$(Configuration)\$(MSBuildProjectName).log - - - - - $(BuildOutputDir) - - - - - - - - - - - - - - - Create - Create - - - - - - - - - \ No newline at end of file diff --git a/Scalar.ReadObjectHook/Scalar.ReadObjectHook.Windows.vcxproj.filters b/Scalar.ReadObjectHook/Scalar.ReadObjectHook.Windows.vcxproj.filters deleted file mode 100644 index b7c3c28c71..0000000000 --- a/Scalar.ReadObjectHook/Scalar.ReadObjectHook.Windows.vcxproj.filters +++ /dev/null @@ -1,59 +0,0 @@ - - - - - {4FC737F1-C7A5-4376-A066-2A32D752A2FF} - cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx - - - {93995380-89BD-4b04-88EB-625FBE52EBFB} - h;hh;hpp;hxx;hm;inl;inc;xsd - - - {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} - rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms - - - {c3243239-d853-4df9-bdbb-9a4efa72a827} - - - {e6c30bd2-e246-47d9-ad10-137165f4628c} - - - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Shared Header Files - - - - - Source Files - - - Source Files - - - Source Files - - - Shared Source Files - - - - - Resource Files - - - diff --git a/Scalar.ReadObjectHook/Version.rc b/Scalar.ReadObjectHook/Version.rc deleted file mode 100644 index 8000a42a82..0000000000 --- a/Scalar.ReadObjectHook/Version.rc +++ /dev/null @@ -1,100 +0,0 @@ -// Microsoft Visual C++ generated resource script. -// -#include "resource.h" -#include "CommonVersionHeader.h" - -#define APSTUDIO_READONLY_SYMBOLS -///////////////////////////////////////////////////////////////////////////// -// -// Generated from the TEXTINCLUDE 2 resource. -// -#include "winres.h" - -///////////////////////////////////////////////////////////////////////////// -#undef APSTUDIO_READONLY_SYMBOLS - -///////////////////////////////////////////////////////////////////////////// -// English (United States) resources - -#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU) -LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US - -#ifdef APSTUDIO_INVOKED -///////////////////////////////////////////////////////////////////////////// -// -// TEXTINCLUDE -// - -1 TEXTINCLUDE -BEGIN - "resource.h\0" -END - -2 TEXTINCLUDE -BEGIN - "#include ""winres.h""\r\n" - "\0" -END - -3 TEXTINCLUDE -BEGIN - "\r\n" - "\0" -END - -#endif // APSTUDIO_INVOKED - - -///////////////////////////////////////////////////////////////////////////// -// -// Version -// - -VS_VERSION_INFO VERSIONINFO - FILEVERSION SCALAR_FILE_VERSION - PRODUCTVERSION SCALAR_PRODUCT_VERSION - FILEFLAGSMASK 0x3fL -#ifdef _DEBUG - FILEFLAGS 0x1L -#else - FILEFLAGS 0x0L -#endif - FILEOS 0x40004L - FILETYPE 0x1L - FILESUBTYPE 0x0L -BEGIN - BLOCK "StringFileInfo" - BEGIN - BLOCK "040904b0" - BEGIN - VALUE "CompanyName", "Microsoft" - VALUE "FileDescription", "Scalar.ReadObjectHook" - VALUE "FileVersion", SCALAR_FILE_VERSION_STRING - VALUE "InternalName", "Scalar.ReadObjectHook.exe" - VALUE "LegalCopyright", "Copyright (c) Microsoft 2019" - VALUE "OriginalFilename", "Scalar.ReadObjectHook.exe" - VALUE "ProductName", "Scalar.ReadObjectHook" - VALUE "ProductVersion", SCALAR_PRODUCT_VERSION_STRING - END - END - BLOCK "VarFileInfo" - BEGIN - VALUE "Translation", 0x409, 1200 - END -END - -#endif // English (United States) resources -///////////////////////////////////////////////////////////////////////////// - - - -#ifndef APSTUDIO_INVOKED -///////////////////////////////////////////////////////////////////////////// -// -// Generated from the TEXTINCLUDE 3 resource. -// - - -///////////////////////////////////////////////////////////////////////////// -#endif // not APSTUDIO_INVOKED - diff --git a/Scalar.ReadObjectHook/main.cpp b/Scalar.ReadObjectHook/main.cpp deleted file mode 100644 index 9674a1b74a..0000000000 --- a/Scalar.ReadObjectHook/main.cpp +++ /dev/null @@ -1,150 +0,0 @@ -// Scalar.ReadObjectHook -// -// When Scalar installs Scalar.ReadObjectHook, it copies the file to -// the .git\hooks folder, and renames the executable to read-object -// read-object is called by git when it fails to find the object it's looking for on disk. -// -// Git and read-object negotiate an interface and capabilities then git issues a "get" command for the missing SHA. -// See Git Documentation/Technical/read-object-protocol.txt for details. -// Scalar.ReadObjectHook decides which Scalar instance to connect to based on its path. -// It then connects to Scalar and asks Scalar to download the requested object (to the .git\objects folder). - -#include "stdafx.h" -#include "packet.h" -#include "common.h" - -#define MAX_PACKET_LENGTH 512 -#define SHA1_LENGTH 40 -#define DLO_REQUEST_LENGTH (4 + SHA1_LENGTH + 1) - -// Expected response: -// "S\x3" -> Success -// "F\x3" -> Failure -#define DLO_RESPONSE_LENGTH 2 - -enum ReadObjectHookErrorReturnCode -{ - ErrorReadObjectProtocol = ReturnCode::LastError + 1, -}; - -int DownloadSHA(PIPE_HANDLE pipeHandle, const char *sha1) -{ - // Construct download request message - // Format: "DLO|<40 character SHA>" - // Example: "DLO|920C34DCDDFC8F07AC4704C8C0D087D6F2095729" - char request[DLO_REQUEST_LENGTH+1]; - if (snprintf(request, DLO_REQUEST_LENGTH+1, "DLO|%s\x3", sha1) != DLO_REQUEST_LENGTH) - { - die(ReturnCode::InvalidSHA, "First argument must be a 40 character SHA, actual value: %s\n", sha1); - } - - unsigned long bytesWritten; - int error = 0; - bool success = WriteToPipe( - pipeHandle, - request, - DLO_REQUEST_LENGTH, - &bytesWritten, - &error); - - if (!success || bytesWritten != DLO_REQUEST_LENGTH) - { - die(ReturnCode::PipeWriteFailed, "Failed to write to pipe (%d)\n", error); - } - - char response[DLO_RESPONSE_LENGTH]; - unsigned long totalBytesRead = 0; - error = 0; - do - { - unsigned long bytesRead = 0; - success = ReadFromPipe( - pipeHandle, - response + totalBytesRead, - sizeof(response) - (sizeof(char) * totalBytesRead), - &bytesRead, - &error); - totalBytesRead += bytesRead; - } while (success && totalBytesRead < DLO_RESPONSE_LENGTH); - - if (!success) - { - die(ReturnCode::PipeReadFailed, "Read response from pipe failed (%d)\n", error); - } - - return *response == 'S' ? ReturnCode::Success : ReturnCode::FailureToDownload; -} - -int main(int, char *argv[]) -{ - char packet_buffer[MAX_PACKET_LENGTH]; - size_t len; - int err; - - DisableCRLFTranslationOnStdPipes(); - - packet_txt_read(packet_buffer, sizeof(packet_buffer)); - if (strcmp(packet_buffer, "git-read-object-client")) - { - die(ReadObjectHookErrorReturnCode::ErrorReadObjectProtocol, "Bad welcome message\n"); - } - - packet_txt_read(packet_buffer, sizeof(packet_buffer)); - if (strcmp(packet_buffer, "version=1")) - { - die(ReadObjectHookErrorReturnCode::ErrorReadObjectProtocol, "Bad version\n"); - } - - if (packet_txt_read(packet_buffer, sizeof(packet_buffer))) - { - die(ReadObjectHookErrorReturnCode::ErrorReadObjectProtocol, "Bad version end\n"); - } - - packet_txt_write("git-read-object-server"); - packet_txt_write("version=1"); - packet_flush(); - - packet_txt_read(packet_buffer, sizeof(packet_buffer)); - if (strcmp(packet_buffer, "capability=get")) - { - die(ReadObjectHookErrorReturnCode::ErrorReadObjectProtocol, "Bad capability\n"); - } - - if (packet_txt_read(packet_buffer, sizeof(packet_buffer))) - { - die(ReadObjectHookErrorReturnCode::ErrorReadObjectProtocol, "Bad capability end\n"); - } - - packet_txt_write("capability=get"); - packet_flush(); - - PATH_STRING pipeName(GetScalarPipeName(argv[0])); - - PIPE_HANDLE pipeHandle = CreatePipeToScalar(pipeName); - - while (1) - { - packet_txt_read(packet_buffer, sizeof(packet_buffer)); - if (strcmp(packet_buffer, "command=get")) - { - die(ReadObjectHookErrorReturnCode::ErrorReadObjectProtocol, "Bad command\n"); - } - - len = packet_txt_read(packet_buffer, sizeof(packet_buffer)); - if ((len != SHA1_LENGTH + 5) || strncmp(packet_buffer, "sha1=", 5)) - { - die(ReadObjectHookErrorReturnCode::ErrorReadObjectProtocol, "Bad sha1 in get command\n"); - } - - if (packet_txt_read(packet_buffer, sizeof(packet_buffer))) - { - die(ReadObjectHookErrorReturnCode::ErrorReadObjectProtocol, "Bad command end\n"); - } - - err = DownloadSHA(pipeHandle, packet_buffer + 5); - packet_txt_write(err ? "status=error" : "status=success"); - packet_flush(); - } - - // we'll never reach here as the signal to exit is having stdin closed which is handled in packet_bin_read -} diff --git a/Scalar.ReadObjectHook/packet.cpp b/Scalar.ReadObjectHook/packet.cpp deleted file mode 100644 index 50d63e41d5..0000000000 --- a/Scalar.ReadObjectHook/packet.cpp +++ /dev/null @@ -1,156 +0,0 @@ -#include "stdafx.h" -#include "packet.h" -#include "common.h" - -static void set_packet_header(char *buf, const size_t size) -{ - static char hexchar[] = "0123456789abcdef"; - -#define hex(a) (hexchar[(a) & 15]) - buf[0] = hex(size >> 12); - buf[1] = hex(size >> 8); - buf[2] = hex(size >> 4); - buf[3] = hex(size); -#undef hex -} - -const signed char hexval_table[256] = { - -1, -1, -1, -1, -1, -1, -1, -1, /* 00-07 */ - -1, -1, -1, -1, -1, -1, -1, -1, /* 08-0f */ - -1, -1, -1, -1, -1, -1, -1, -1, /* 10-17 */ - -1, -1, -1, -1, -1, -1, -1, -1, /* 18-1f */ - -1, -1, -1, -1, -1, -1, -1, -1, /* 20-27 */ - -1, -1, -1, -1, -1, -1, -1, -1, /* 28-2f */ - 0, 1, 2, 3, 4, 5, 6, 7, /* 30-37 */ - 8, 9, -1, -1, -1, -1, -1, -1, /* 38-3f */ - -1, 10, 11, 12, 13, 14, 15, -1, /* 40-47 */ - -1, -1, -1, -1, -1, -1, -1, -1, /* 48-4f */ - -1, -1, -1, -1, -1, -1, -1, -1, /* 50-57 */ - -1, -1, -1, -1, -1, -1, -1, -1, /* 58-5f */ - -1, 10, 11, 12, 13, 14, 15, -1, /* 60-67 */ - -1, -1, -1, -1, -1, -1, -1, -1, /* 68-67 */ - -1, -1, -1, -1, -1, -1, -1, -1, /* 70-77 */ - -1, -1, -1, -1, -1, -1, -1, -1, /* 78-7f */ - -1, -1, -1, -1, -1, -1, -1, -1, /* 80-87 */ - -1, -1, -1, -1, -1, -1, -1, -1, /* 88-8f */ - -1, -1, -1, -1, -1, -1, -1, -1, /* 90-97 */ - -1, -1, -1, -1, -1, -1, -1, -1, /* 98-9f */ - -1, -1, -1, -1, -1, -1, -1, -1, /* a0-a7 */ - -1, -1, -1, -1, -1, -1, -1, -1, /* a8-af */ - -1, -1, -1, -1, -1, -1, -1, -1, /* b0-b7 */ - -1, -1, -1, -1, -1, -1, -1, -1, /* b8-bf */ - -1, -1, -1, -1, -1, -1, -1, -1, /* c0-c7 */ - -1, -1, -1, -1, -1, -1, -1, -1, /* c8-cf */ - -1, -1, -1, -1, -1, -1, -1, -1, /* d0-d7 */ - -1, -1, -1, -1, -1, -1, -1, -1, /* d8-df */ - -1, -1, -1, -1, -1, -1, -1, -1, /* e0-e7 */ - -1, -1, -1, -1, -1, -1, -1, -1, /* e8-ef */ - -1, -1, -1, -1, -1, -1, -1, -1, /* f0-f7 */ - -1, -1, -1, -1, -1, -1, -1, -1, /* f8-ff */ -}; - -static inline unsigned int hexval(unsigned char c) -{ - return hexval_table[c]; -} - -static inline int hex2chr(const char *s) -{ - int val = hexval(s[0]); - return (val < 0) ? val : (val << 4) | hexval(s[1]); -} - -static int packet_length(const char *packetlen) -{ - int val = hex2chr(packetlen); - return (val < 0) ? val : (val << 8) | hex2chr(packetlen + 2); -} - -static size_t packet_bin_read(void *buf, size_t count, FILE *stream) -{ - char packetlen[4]; - size_t len, ret; - - /* if we timeout waiting for input, exit and git will restart us if needed */ - size_t bytes_read = fread(packetlen, 1, 4, stream); - if (0 == bytes_read) - { - exit(0); - } - if (4 != bytes_read) - { - die(-1, "invalid packet length"); - } - - len = packet_length(packetlen); - if (!len) - { - return 0; - } - if (len < 4) - { - die(-1, "protocol error: bad line length character: %.4s", packetlen); - } - len -= 4; - if (len >= count) - { - die(-1, "protocol error: bad line length %zu", len); - } - ret = fread(buf, 1, len, stream); - if (ret != len) - { - die(-1, "invalid packet (%zu bytes expected; %zu bytes read)", len, ret); - } - - return len; -} - -size_t packet_txt_read(char *buf, size_t count, FILE *stream) -{ - size_t len; - - len = packet_bin_read(buf, count, stream); - if (len && buf[len - 1] == '\n') - { - len--; - } - - buf[len] = 0; - return len; -} - -void packet_txt_write(const char *buf, FILE *stream) -{ - char packetlen[4]; - size_t len, count = strlen(buf); - - set_packet_header(packetlen, count + 5); - len = fwrite(packetlen, 1, 4, stream); - if (len != 4) - { - die(-1, "error writing packet length"); - } - len = fwrite(buf, 1, count, stream); - if (len != count) - { - die(-1, "error writing packet"); - } - len = fwrite("\n", 1, 1, stream); - if (len != 1) - { - die(-1, "error writing packet"); - } - fflush(stream); -} - -void packet_flush(FILE *stream) -{ - size_t len; - - len = fwrite("0000", 1, 4, stream); - if (len != 4) - { - die(-1, "error writing flush packet"); - } - fflush(stream); -} diff --git a/Scalar.ReadObjectHook/packet.h b/Scalar.ReadObjectHook/packet.h deleted file mode 100644 index 7de2697466..0000000000 --- a/Scalar.ReadObjectHook/packet.h +++ /dev/null @@ -1,6 +0,0 @@ -#pragma once -#include - -size_t packet_txt_read(char *buf, size_t count, FILE *stream = stdin); -void packet_txt_write(const char *buf, FILE *stream = stdout); -void packet_flush(FILE *stream = stdout); diff --git a/Scalar.ReadObjectHook/resource.h b/Scalar.ReadObjectHook/resource.h deleted file mode 100644 index 7bc0b68ce0..0000000000 --- a/Scalar.ReadObjectHook/resource.h +++ /dev/null @@ -1,14 +0,0 @@ -//{{NO_DEPENDENCIES}} -// Microsoft Visual C++ generated include file. -// Used by Version.rc - -// Next default values for new objects -// -#ifdef APSTUDIO_INVOKED -#ifndef APSTUDIO_READONLY_SYMBOLS -#define _APS_NEXT_RESOURCE_VALUE 101 -#define _APS_NEXT_COMMAND_VALUE 40001 -#define _APS_NEXT_CONTROL_VALUE 1001 -#define _APS_NEXT_SYMED_VALUE 101 -#endif -#endif diff --git a/Scalar.ReadObjectHook/stdafx.cpp b/Scalar.ReadObjectHook/stdafx.cpp deleted file mode 100644 index d408aabbd0..0000000000 --- a/Scalar.ReadObjectHook/stdafx.cpp +++ /dev/null @@ -1,8 +0,0 @@ -// stdafx.cpp : source file that includes just the standard includes -// Scalar.ReadObjectHook.pch will be the pre-compiled header -// stdafx.obj will contain the pre-compiled type information - -#include "stdafx.h" - -// TODO: reference any additional headers you need in STDAFX.H -// and not in this file diff --git a/Scalar.ReadObjectHook/stdafx.h b/Scalar.ReadObjectHook/stdafx.h deleted file mode 100644 index 660b922b92..0000000000 --- a/Scalar.ReadObjectHook/stdafx.h +++ /dev/null @@ -1,14 +0,0 @@ -// stdafx.h : include file for standard system include files, -// or project specific include files that are used frequently, but -// are changed infrequently -// - -#pragma once - -#ifdef _WIN32 -#include "targetver.h" -#include -#endif - -#include -#include diff --git a/Scalar.ReadObjectHook/targetver.h b/Scalar.ReadObjectHook/targetver.h deleted file mode 100644 index 87c0086de7..0000000000 --- a/Scalar.ReadObjectHook/targetver.h +++ /dev/null @@ -1,8 +0,0 @@ -#pragma once - -// Including SDKDDKVer.h defines the highest available Windows platform. - -// If you wish to build your application for a previous Windows platform, include WinSDKVer.h and -// set the _WIN32_WINNT macro to the platform you wish to support before including SDKDDKVer.h. - -#include diff --git a/Scalar.SignFiles/Scalar.SignFiles.csproj b/Scalar.SignFiles/Scalar.SignFiles.csproj index 2325fb6637..f878d5880a 100644 --- a/Scalar.SignFiles/Scalar.SignFiles.csproj +++ b/Scalar.SignFiles/Scalar.SignFiles.csproj @@ -38,7 +38,6 @@ $(BuildOutputDir)\Scalar.Common\bin\$(Platform)\$(Configuration)\netstandard2.0\Scalar.Common.dll; $(BuildOutputDir)\Scalar.Mount.Windows\bin\$(Platform)\$(Configuration)\Scalar.Mount.exe; $(BuildOutputDir)\Scalar.Platform.Windows\bin\$(Platform)\$(Configuration)\Scalar.Platform.Windows.dll; - $(BuildOutputDir)\Scalar.ReadObjectHook.Windows\bin\$(Platform)\$(Configuration)\Scalar.ReadObjectHook.exe; $(BuildOutputDir)\Scalar.Service.Windows\bin\$(Platform)\$(Configuration)\Scalar.Service.exe; $(BuildOutputDir)\Scalar.Service.UI\bin\$(Platform)\$(Configuration)\Scalar.Service.UI.exe; $(BuildOutputDir)\Scalar.Upgrader\bin\$(Platform)\$(Configuration)\net461\Scalar.Upgrader.exe; diff --git a/Scalar.UnitTests/Prefetch/BatchObjectDownloadStageTests.cs b/Scalar.UnitTests/Prefetch/BatchObjectDownloadStageTests.cs deleted file mode 100644 index 0c4e191bef..0000000000 --- a/Scalar.UnitTests/Prefetch/BatchObjectDownloadStageTests.cs +++ /dev/null @@ -1,77 +0,0 @@ -using NUnit.Framework; -using Scalar.Common.Prefetch.Pipeline; -using Scalar.Tests.Should; -using Scalar.UnitTests.Category; -using Scalar.UnitTests.Mock.Common; -using Scalar.UnitTests.Mock.Git; -using System; -using System.Collections.Concurrent; - -namespace Scalar.UnitTests.Prefetch -{ - [TestFixture] - public class BatchObjectDownloadStageTests - { - private const int MaxParallel = 1; - private const int ChunkSize = 2; - - // This test confirms that if two objects are downloaded at the same time and the second - // object's download fails, the first object should not be downloaded again - [TestCase] - [Category(CategoryConstants.ExceptionExpected)] - public void OnlyRequestsObjectsNotDownloaded() - { - string obj1Sha = new string('1', 40); - string obj2Sha = new string('2', 40); - - BlockingCollection input = new BlockingCollection(); - input.Add(obj1Sha); - input.Add(obj2Sha); - input.CompleteAdding(); - - int obj1Count = 0; - int obj2Count = 0; - - Func objectResolver = (oid) => - { - if (oid.Equals(obj1Sha)) - { - obj1Count++; - return "Object1Contents"; - } - - if (oid.Equals(obj2Sha) && obj2Count++ == 1) - { - return "Object2Contents"; - } - - return null; - }; - - BlockingCollection output = new BlockingCollection(); - MockTracer tracer = new MockTracer(); - MockScalarEnlistment enlistment = new MockScalarEnlistment(); - MockBatchHttpGitObjects httpObjects = new MockBatchHttpGitObjects(tracer, enlistment, objectResolver); - - BatchObjectDownloadStage dut = new BatchObjectDownloadStage( - MaxParallel, - ChunkSize, - input, - output, - tracer, - enlistment, - httpObjects, - new MockPhysicalGitObjects(tracer, null, enlistment, httpObjects)); - - dut.Start(); - dut.WaitForCompletion(); - - input.Count.ShouldEqual(0); - output.Count.ShouldEqual(2); - output.Take().ShouldEqual(obj1Sha); - output.Take().ShouldEqual(obj2Sha); - obj1Count.ShouldEqual(1); - obj2Count.ShouldEqual(2); - } - } -} diff --git a/Scalar.UnitTests/Prefetch/BlobPrefetcherTests.cs b/Scalar.UnitTests/Prefetch/BlobPrefetcherTests.cs deleted file mode 100644 index 99d16ab33a..0000000000 --- a/Scalar.UnitTests/Prefetch/BlobPrefetcherTests.cs +++ /dev/null @@ -1,33 +0,0 @@ -using NUnit.Framework; -using Scalar.Common.Prefetch; -using Scalar.Tests.Should; -using Scalar.UnitTests.Mock.FileSystem; -using System.IO; - -namespace Scalar.UnitTests.Prefetch -{ - [TestFixture] - public class BlobPrefetcherTests - { - [TestCase] - public void AppendToNewlineSeparatedFileTests() - { - MockFileSystem fileSystem = new MockFileSystem(new MockDirectory(Path.Combine("mock:", "Scalar", "UnitTests", "Repo"), null, null)); - - // Validate can write to a file that doesn't exist. - string testFileName = Path.Combine("mock:", "Scalar", "UnitTests", "Repo", "appendTests"); - BlobPrefetcher.AppendToNewlineSeparatedFile(fileSystem, testFileName, "expected content line 1"); - fileSystem.ReadAllText(testFileName).ShouldEqual("expected content line 1\n"); - - // Validate that if the file doesn't end in a newline it gets a newline added. - fileSystem.WriteAllText(testFileName, "existing content"); - BlobPrefetcher.AppendToNewlineSeparatedFile(fileSystem, testFileName, "expected line 2"); - fileSystem.ReadAllText(testFileName).ShouldEqual("existing content\nexpected line 2\n"); - - // Validate that if the file ends in a newline, we don't end up with two newlines - fileSystem.WriteAllText(testFileName, "existing content\n"); - BlobPrefetcher.AppendToNewlineSeparatedFile(fileSystem, testFileName, "expected line 2"); - fileSystem.ReadAllText(testFileName).ShouldEqual("existing content\nexpected line 2\n"); - } - } -} diff --git a/Scalar.UnitTests/Prefetch/DiffHelperTests.cs b/Scalar.UnitTests/Prefetch/DiffHelperTests.cs deleted file mode 100644 index 94b27bd141..0000000000 --- a/Scalar.UnitTests/Prefetch/DiffHelperTests.cs +++ /dev/null @@ -1,248 +0,0 @@ -using NUnit.Framework; -using Scalar.Common.Git; -using Scalar.Common.Prefetch.Git; -using Scalar.Tests; -using Scalar.Tests.Should; -using Scalar.UnitTests.Mock.Common; -using Scalar.UnitTests.Mock.Git; -using System.Collections.Generic; -using System.IO; -using System.Linq; -using System.Reflection; - -namespace Scalar.UnitTests.Prefetch -{ - [TestFixtureSource(typeof(DataSources), nameof(DataSources.AllBools))] - public class DiffHelperTests - { - public DiffHelperTests(bool symLinkSupport) - { - this.IncludeSymLinks = symLinkSupport; - } - - public bool IncludeSymLinks { get; set; } - - // Make two commits. The first should look like this: - // recursiveDelete - // recursiveDelete/subfolder - // recursiveDelete/subfolder/childFile.txt - // fileToBecomeFolder - // fileToDelete.txt - // fileToEdit.txt - // fileToRename.txt - // fileToRenameEdit.txt - // folderToBeFile - // folderToBeFile/childFile.txt - // folderToDelete - // folderToDelete/childFile.txt - // folderToEdit - // folderToEdit/childFile.txt - // folderToRename - // folderToRename/childFile.txt - // symLinkToBeCreated.txt - // - // The second should follow the action indicated by the file/folder name: - // eg. recursiveDelete should run "rmdir /s/q recursiveDelete" - // eg. folderToBeFile should be deleted and replaced with a file of the same name - // Note that each childFile.txt should have unique contents, but is only a placeholder to force git to add a folder. - // - // Then to generate the diffs, run: - // git diff-tree -r -t Head~1 Head > forward.txt - // git diff-tree -r -t Head Head ~1 > backward.txt - [TestCase] - public void CanParseDiffForwards() - { - MockTracer tracer = new MockTracer(); - DiffHelper diffForwards = new DiffHelper(tracer, new MockScalarEnlistment(), new List(), new List(), includeSymLinks: this.IncludeSymLinks); - diffForwards.ParseDiffFile(GetDataPath("forward.txt")); - - // File added, file edited, file renamed, folder => file, edit-rename file, SymLink added (if applicable) - // Children of: Add folder, Renamed folder, edited folder, file => folder - diffForwards.RequiredBlobs.Count.ShouldEqual(diffForwards.ShouldIncludeSymLinks ? 10 : 9); - - diffForwards.FileAddOperations.ContainsKey("3bd509d373734a9f9685d6a73ba73324f72931e3").ShouldEqual(diffForwards.ShouldIncludeSymLinks); - - // File deleted, folder deleted, file > folder, edit-rename - diffForwards.FileDeleteOperations.Count.ShouldEqual(4); - - // Includes children of: Recursive delete folder, deleted folder, renamed folder, and folder => file - diffForwards.TotalFileDeletes.ShouldEqual(8); - - // Folder created, folder edited, folder deleted, folder renamed (add + delete), - // folder => file, file => folder, recursive delete (top-level only) - diffForwards.DirectoryOperations.Count.ShouldEqual(8); - - // Should also include the deleted folder of recursive delete - diffForwards.TotalDirectoryOperations.ShouldEqual(9); - } - - // Parses Diff B => A - [TestCase] - public void CanParseBackwardsDiff() - { - MockTracer tracer = new MockTracer(); - DiffHelper diffBackwards = new DiffHelper(tracer, new Mock.Common.MockScalarEnlistment(), new List(), new List(), includeSymLinks: this.IncludeSymLinks); - diffBackwards.ParseDiffFile(GetDataPath("backward.txt")); - - // File > folder, deleted file, edited file, renamed file, rename-edit file - // Children of file > folder, renamed folder, deleted folder, recursive delete file, edited folder - diffBackwards.RequiredBlobs.Count.ShouldEqual(10); - - // File added, folder > file, moved folder, added folder - diffBackwards.FileDeleteOperations.Count.ShouldEqual(4); - - // Also includes, the children of: Folder added, folder renamed, file => folder - diffBackwards.TotalFileDeletes.ShouldEqual(7); - - // Folder created, folder edited, folder deleted, folder renamed (add + delete), - // folder => file, file => folder, recursive delete (include subfolder) - diffBackwards.TotalDirectoryOperations.ShouldEqual(9); - } - - // Delete a folder with two sub folders each with a single file - // Readd it with a different casing and same contents - [TestCase] - public void ParsesCaseChangesAsAdds() - { - MockTracer tracer = new MockTracer(); - DiffHelper diffBackwards = new DiffHelper(tracer, new Mock.Common.MockScalarEnlistment(), new List(), new List(), includeSymLinks: this.IncludeSymLinks); - diffBackwards.ParseDiffFile(GetDataPath("caseChange.txt")); - - diffBackwards.RequiredBlobs.Count.ShouldEqual(2); - diffBackwards.FileAddOperations.Sum(list => list.Value.Count).ShouldEqual(2); - - diffBackwards.FileDeleteOperations.Count.ShouldEqual(0); - diffBackwards.TotalFileDeletes.ShouldEqual(0); - - diffBackwards.DirectoryOperations.ShouldNotContain(entry => entry.Operation == DiffTreeResult.Operations.Delete); - diffBackwards.TotalDirectoryOperations.ShouldEqual(3); - } - - [TestCase] - public void DetectsFailuresInDiffTree() - { - MockTracer tracer = new MockTracer(); - MockGitProcess gitProcess = new MockGitProcess(); - gitProcess.SetExpectedCommandResult("diff-tree -r -t sha1 sha2", () => new GitProcess.Result(string.Empty, string.Empty, 1)); - - DiffHelper diffBackwards = new DiffHelper(tracer, new Mock.Common.MockScalarEnlistment(), gitProcess, new List(), new List(), includeSymLinks: this.IncludeSymLinks); - diffBackwards.PerformDiff("sha1", "sha2"); - diffBackwards.HasFailures.ShouldEqual(true); - } - - [TestCase] - public void DetectsFailuresInLsTree() - { - MockTracer tracer = new MockTracer(); - MockGitProcess gitProcess = new MockGitProcess(); - gitProcess.SetExpectedCommandResult("ls-tree -r -t sha1", () => new GitProcess.Result(string.Empty, string.Empty, 1)); - - DiffHelper diffBackwards = new DiffHelper(tracer, new Mock.Common.MockScalarEnlistment(), gitProcess, new List(), new List(), includeSymLinks: this.IncludeSymLinks); - diffBackwards.PerformDiff(null, "sha1"); - diffBackwards.HasFailures.ShouldEqual(true); - } - - [TestCase] - public void GenerateRecursiveAndParentPathSets() - { - char dir = Path.DirectorySeparatorChar; - List folderList = new List(); - CheckGenerateRecursiveAndParentPathSets( - folderList, - expectedParentFolders: new HashSet(), - expectedMaxFolderPathDepth: 0); - - folderList = new List { $"A{dir}" }; - CheckGenerateRecursiveAndParentPathSets( - folderList, - expectedParentFolders: new HashSet(), - expectedMaxFolderPathDepth: 1); - - folderList = new List { $"A{dir}", $"A{dir}B{dir}" }; - CheckGenerateRecursiveAndParentPathSets( - folderList, - expectedParentFolders: new HashSet { $"A{dir}" }, - expectedMaxFolderPathDepth: 2); - - folderList = new List { $"A{dir}", $"A{dir}B{dir}", $"C{dir}" }; - CheckGenerateRecursiveAndParentPathSets( - folderList, - expectedParentFolders: new HashSet { $"A{dir}" }, - expectedMaxFolderPathDepth: 2); - - folderList = new List { $"A{dir}", $"A{dir}B{dir}", $"C{dir}", $"G{dir}H{dir}I{dir}J{dir}" }; - CheckGenerateRecursiveAndParentPathSets( - folderList, - expectedParentFolders: new HashSet { $"A{dir}", $"G{dir}", $"G{dir}H{dir}", $"G{dir}H{dir}I{dir}" }, - expectedMaxFolderPathDepth: 4); - } - - [TestCase] - public void PathMatchesFoldersReturnsFalseWithNoFoldersList() - { - MockTracer tracer = new MockTracer(); - DiffHelper diffHelper = new DiffHelper(tracer, new MockScalarEnlistment(), fileList: new List(), folderList: new List(), includeSymLinks: false); - - diffHelper.PathMatchesFolders("a.txt").ShouldBeFalse("Paths (even in root) should not match if there is no folders list"); - } - - [TestCase] - public void PathMatchesFoldersTests() - { - char dir = Path.DirectorySeparatorChar; - List folderList = new List - { - $"A{dir}", - $"a{dir}b{dir}", - $"C{dir}", - $"G{dir}H{dir}I{dir}J{dir}" - }; - - MockTracer tracer = new MockTracer(); - DiffHelper diffHelper = new DiffHelper(tracer, new MockScalarEnlistment(), fileList: new List(), folderList: folderList, includeSymLinks: false); - - diffHelper.PathMatchesFolders("a").ShouldBeTrue("Paths in the root should always be included"); - diffHelper.PathMatchesFolders("C.txt").ShouldBeTrue("Paths in the root should always be included"); - - diffHelper.PathMatchesFolders($"A{dir}D{dir}foo.txt").ShouldBeTrue("Descendants of folders in the list should be included"); - diffHelper.PathMatchesFolders($"A{dir}D{dir}E{dir}foo.txt").ShouldBeTrue("Descendants of folders in the list should be included"); - diffHelper.PathMatchesFolders($"a{dir}d{dir}e{dir}FOO.txt").ShouldBeTrue("Descendants of folders in the list should be included"); - diffHelper.PathMatchesFolders($"C{dir}bar.txt").ShouldBeTrue("Descendants of folders in the list should be included"); - - diffHelper.PathMatchesFolders($"G{dir}foo.txt").ShouldBeTrue("Immediate children of intermediate folders in the list should be included"); - diffHelper.PathMatchesFolders($"G{dir}H{dir}foo.txt").ShouldBeTrue("Immediate children of intermediate folders in the list should be included"); - diffHelper.PathMatchesFolders($"G{dir}H{dir}I{dir}foo.txt").ShouldBeTrue("Immediate children of intermediate folders in the list should be included"); - diffHelper.PathMatchesFolders($"g{dir}h{dir}i{dir}foo.txt").ShouldBeTrue("Immediate children of intermediate folders in the list should be included"); - - // Paths that are not children/descendants should not match - diffHelper.PathMatchesFolders($"B{dir}foo.txt").ShouldBeFalse("Files that are not children/descendants should not be included"); - diffHelper.PathMatchesFolders($"B{dir}D{dir}baz.txt").ShouldBeFalse("Files that are not children/descendants should not be included"); - - // Paths that are not descendants (and not immediate children) of intermediate folders should not match - diffHelper.PathMatchesFolders($"G{dir}H{dir}Z{dir}foo.txt").ShouldBeFalse("Files that are not children/descendants should not be included"); - diffHelper.PathMatchesFolders($"G{dir}H{dir}I{dir}Z{dir}foo.txt").ShouldBeFalse("Files that are not children/descendants should not be included"); - } - - private static void CheckGenerateRecursiveAndParentPathSets( - IEnumerable folderList, - HashSet expectedParentFolders, - int expectedMaxFolderPathDepth) - { - HashSet parentFolders; - HashSet recursiveParents; - int maxRecursiveDepth; - - HashSet expectedRecursiveFolders = new HashSet(folderList); - DiffHelper.GenerateRecursiveAndParentPathSets(folderList, out parentFolders, out recursiveParents, out maxRecursiveDepth); - parentFolders.ShouldMatchInOrder(expectedParentFolders); - recursiveParents.ShouldMatchInOrder(expectedRecursiveFolders); - maxRecursiveDepth.ShouldEqual(expectedMaxFolderPathDepth); - } - - private static string GetDataPath(string fileName) - { - string workingDirectory = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location); - return Path.Combine(workingDirectory, "Data", fileName); - } - } -} diff --git a/Scalar.UnitTests/Prefetch/PrefetchTracingTests.cs b/Scalar.UnitTests/Prefetch/PrefetchTracingTests.cs deleted file mode 100644 index ff3844425b..0000000000 --- a/Scalar.UnitTests/Prefetch/PrefetchTracingTests.cs +++ /dev/null @@ -1,95 +0,0 @@ -using NUnit.Framework; -using Scalar.Common.Prefetch.Pipeline; -using Scalar.Common.Prefetch.Pipeline.Data; -using Scalar.Common.Tracing; -using Scalar.Tests.Should; -using Scalar.UnitTests.Mock.Common; -using Scalar.UnitTests.Mock.Git; -using System.Collections.Concurrent; - -namespace Scalar.UnitTests.Prefetch -{ - [TestFixture] - public class PrefetchTracingTests - { - private const string FakeSha = "fakesha"; - private const string FakeShaContents = "fakeshacontents"; - - [TestCase] - public void ErrorsForBatchObjectDownloadJob() - { - using (ITracer tracer = CreateTracer()) - { - MockScalarEnlistment enlistment = new MockScalarEnlistment(); - MockHttpGitObjects httpGitObjects = new MockHttpGitObjects(tracer, enlistment); - MockPhysicalGitObjects gitObjects = new MockPhysicalGitObjects(tracer, null, enlistment, httpGitObjects); - - BlockingCollection input = new BlockingCollection(); - input.Add(FakeSha); - input.CompleteAdding(); - - BatchObjectDownloadStage dut = new BatchObjectDownloadStage(1, 1, input, new BlockingCollection(), tracer, enlistment, httpGitObjects, gitObjects); - dut.Start(); - dut.WaitForCompletion(); - - string sha; - input.TryTake(out sha).ShouldEqual(false); - - IndexPackRequest request; - dut.AvailablePacks.TryTake(out request).ShouldEqual(false); - } - } - - [TestCase] - public void SuccessForBatchObjectDownloadJob() - { - using (ITracer tracer = CreateTracer()) - { - MockScalarEnlistment enlistment = new MockScalarEnlistment(); - MockHttpGitObjects httpGitObjects = new MockHttpGitObjects(tracer, enlistment); - httpGitObjects.AddBlobContent(FakeSha, FakeShaContents); - MockPhysicalGitObjects gitObjects = new MockPhysicalGitObjects(tracer, null, enlistment, httpGitObjects); - - BlockingCollection input = new BlockingCollection(); - input.Add(FakeSha); - input.CompleteAdding(); - - BatchObjectDownloadStage dut = new BatchObjectDownloadStage(1, 1, input, new BlockingCollection(), tracer, enlistment, httpGitObjects, gitObjects); - dut.Start(); - dut.WaitForCompletion(); - - string sha; - input.TryTake(out sha).ShouldEqual(false); - dut.AvailablePacks.Count.ShouldEqual(0); - - dut.AvailableObjects.Count.ShouldEqual(1); - string output = dut.AvailableObjects.Take(); - output.ShouldEqual(FakeSha); - } - } - - [TestCase] - public void ErrorsForIndexPackFile() - { - using (ITracer tracer = CreateTracer()) - { - MockScalarEnlistment enlistment = new MockScalarEnlistment(); - MockPhysicalGitObjects gitObjects = new MockPhysicalGitObjects(tracer, null, enlistment, null); - - BlockingCollection input = new BlockingCollection(); - BlobDownloadRequest downloadRequest = new BlobDownloadRequest(new string[] { FakeSha }); - input.Add(new IndexPackRequest("mock:\\path\\packFileName", downloadRequest)); - input.CompleteAdding(); - - IndexPackStage dut = new IndexPackStage(1, input, new BlockingCollection(), tracer, gitObjects); - dut.Start(); - dut.WaitForCompletion(); - } - } - - private static ITracer CreateTracer() - { - return new MockTracer(); - } - } -} diff --git a/Scalar.sln b/Scalar.sln index beb929f081..8820dfb608 100644 --- a/Scalar.sln +++ b/Scalar.sln @@ -1,308 +1,286 @@ -Microsoft Visual Studio Solution File, Format Version 12.00 -# Visual Studio 15 -VisualStudioVersion = 15.0.27428.2015 -MinimumVisualStudioVersion = 10.0.40219.1 -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{DCE11095-DA5F-4878-B58D-2702765560F5}" - ProjectSection(SolutionItems) = preProject - .editorconfig = .editorconfig - .gitattributes = .gitattributes - .gitignore = .gitignore - AuthoringTests.md = AuthoringTests.md - nuget.config = nuget.config - Protocol.md = Protocol.md - Readme.md = Readme.md - EndProjectSection -EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Scalar", "Scalar", "{2EF2EC94-3A68-4ED7-9A58-B7057ADBA01C}" - ProjectSection(SolutionItems) = preProject - Scalar.Build\LibGit2Sharp.NativeBinaries.props = Scalar.Build\LibGit2Sharp.NativeBinaries.props - EndProjectSection -EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Scalar.Common", "Scalar.Common\Scalar.Common.csproj", "{374BF1E5-0B2D-4D4A-BD5E-4212299DEF09}" - ProjectSection(ProjectDependencies) = postProject - {A4984251-840E-4622-AD0C-66DFCE2B2574} = {A4984251-840E-4622-AD0C-66DFCE2B2574} - EndProjectSection -EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Scalar.Tests", "Scalar.Tests\Scalar.Tests.csproj", "{72701BC3-5DA9-4C7A-BF10-9E98C9FC8EAC}" - ProjectSection(ProjectDependencies) = postProject - {A4984251-840E-4622-AD0C-66DFCE2B2574} = {A4984251-840E-4622-AD0C-66DFCE2B2574} - EndProjectSection -EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Scalar Tests", "Scalar Tests", "{C41F10F9-1163-4CFA-A465-EA728F75E9FA}" -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Scalar.UnitTests.Windows", "Scalar.UnitTests.Windows\Scalar.UnitTests.Windows.csproj", "{8E0D0989-21F6-4DD8-946C-39F992523CC6}" -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Scalar.Service.Windows", "Scalar.Service\Scalar.Service.Windows.csproj", "{B8C1DFBA-CAFD-4F7E-A1A3-E11907B5467B}" - ProjectSection(ProjectDependencies) = postProject - {5A6656D5-81C7-472C-9DC8-32D071CB2258} = {5A6656D5-81C7-472C-9DC8-32D071CB2258} - EndProjectSection -EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Scalar.Service.Mac", "Scalar.Service\Scalar.Service.Mac.csproj", "{03769A07-F216-456B-886B-E07CAF6C5E81}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Scalar.ReadObjectHook.Windows", "Scalar.ReadObjectHook\Scalar.ReadObjectHook.Windows.vcxproj", "{5A6656D5-81C7-472C-9DC8-32D071CB2258}" - ProjectSection(ProjectDependencies) = postProject - {A4984251-840E-4622-AD0C-66DFCE2B2574} = {A4984251-840E-4622-AD0C-66DFCE2B2574} - EndProjectSection -EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Scripts", "Scripts", "{28674A4B-1223-4633-A460-C8CC39B09318}" - ProjectSection(SolutionItems) = preProject - Scripts\CreateCommonAssemblyVersion.bat = Scripts\CreateCommonAssemblyVersion.bat - Scripts\CreateCommonCliAssemblyVersion.bat = Scripts\CreateCommonCliAssemblyVersion.bat - Scripts\CreateCommonVersionHeader.bat = Scripts\CreateCommonVersionHeader.bat - Scripts\RunFunctionalTests.bat = Scripts\RunFunctionalTests.bat - Scripts\RunUnitTests.bat = Scripts\RunUnitTests.bat - EndProjectSection -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Scalar.Service.UI", "Scalar.Service.UI\Scalar.Service.UI.csproj", "{93B403FD-DAFB-46C5-9636-B122792A548A}" -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Scalar.PreBuild", "Scalar.Build\Scalar.PreBuild.csproj", "{A4984251-840E-4622-AD0C-66DFCE2B2574}" -EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Build", "Build", "{AB0D9230-3893-4486-8899-F9C871FB5D5F}" -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Scalar.Installer.Windows", "Scalar.Installer.Windows\Scalar.Installer.Windows.csproj", "{3AB4FB1F-9E23-4CD8-BFAC-8A2221C8F893}" - ProjectSection(ProjectDependencies) = postProject - {2F63B22B-EE26-4266-BF17-28A9146483A1} = {2F63B22B-EE26-4266-BF17-28A9146483A1} - EndProjectSection -EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Scalar.Installer.Mac", "Scalar.Installer.Mac\Scalar.Installer.Mac.csproj", "{25229A04-6554-49B1-A95A-3F3B76C5B0C8}" - ProjectSection(ProjectDependencies) = postProject - {03769A07-F216-456B-886B-E07CAF6C5E81} = {03769A07-F216-456B-886B-E07CAF6C5E81} - {28939122-7263-41E7-A7E2-CBFB01AD6A04} = {28939122-7263-41E7-A7E2-CBFB01AD6A04} - {A4984251-840E-4622-AD0C-66DFCE2B2574} = {A4984251-840E-4622-AD0C-66DFCE2B2574} - {1DAC3DA6-3D21-4917-B9A8-D60C8712252A} = {1DAC3DA6-3D21-4917-B9A8-D60C8712252A} - {374BF1E5-0B2D-4D4A-BD5E-4212299DEF09} = {374BF1E5-0B2D-4D4A-BD5E-4212299DEF09} - {35CA4DFB-1320-4055-B8F6-F12E0F252FF0} = {35CA4DFB-1320-4055-B8F6-F12E0F252FF0} - {AECEC217-2499-403D-B0BB-2962B9BE5970} = {AECEC217-2499-403D-B0BB-2962B9BE5970} - EndProjectSection -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Scalar.SignFiles", "Scalar.SignFiles\Scalar.SignFiles.csproj", "{2F63B22B-EE26-4266-BF17-28A9146483A1}" - ProjectSection(ProjectDependencies) = postProject - {17498502-AEFF-4E70-90CC-1D0B56A8ADF5} = {17498502-AEFF-4E70-90CC-1D0B56A8ADF5} - {32220664-594C-4425-B9A0-88E0BE2F3D2A} = {32220664-594C-4425-B9A0-88E0BE2F3D2A} - {B8C1DFBA-CAFD-4F7E-A1A3-E11907B5467B} = {B8C1DFBA-CAFD-4F7E-A1A3-E11907B5467B} - {5A6656D5-81C7-472C-9DC8-32D071CB2258} = {5A6656D5-81C7-472C-9DC8-32D071CB2258} - {374BF1E5-0B2D-4D4A-BD5E-4212299DEF09} = {374BF1E5-0B2D-4D4A-BD5E-4212299DEF09} - {4CE404E7-D3FC-471C-993C-64615861EA63} = {4CE404E7-D3FC-471C-993C-64615861EA63} - {93B403FD-DAFB-46C5-9636-B122792A548A} = {93B403FD-DAFB-46C5-9636-B122792A548A} - {AECEC217-2499-403D-B0BB-2962B9BE5970} = {AECEC217-2499-403D-B0BB-2962B9BE5970} - EndProjectSection -EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Scalar.Platform.Mac", "Scalar.Platform.Mac\Scalar.Platform.Mac.csproj", "{1DAC3DA6-3D21-4917-B9A8-D60C8712252A}" -EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Scalar.Platform.POSIX", "Scalar.Platform.POSIX\Scalar.Platform.POSIX.csproj", "{15FAE44C-0D21-4312-9FD3-28F05A5AB7A6}" -EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Scalar.UnitTests", "Scalar.UnitTests\Scalar.UnitTests.csproj", "{0D434FA7-6D8C-481E-B0CE-779B59EAEF53}" -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Scalar.Platform.Windows", "Scalar.Platform.Windows\Scalar.Platform.Windows.csproj", "{4CE404E7-D3FC-471C-993C-64615861EA63}" -EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Scalar.Mac", "Scalar\Scalar.Mac.csproj", "{28939122-7263-41E7-A7E2-CBFB01AD6A04}" -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Scalar.Windows", "Scalar\Scalar.Windows.csproj", "{32220664-594C-4425-B9A0-88E0BE2F3D2A}" - ProjectSection(ProjectDependencies) = postProject - {5A6656D5-81C7-472C-9DC8-32D071CB2258} = {5A6656D5-81C7-472C-9DC8-32D071CB2258} - EndProjectSection -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Scalar.Mount.Windows", "Scalar.Mount\Scalar.Mount.Windows.csproj", "{17498502-AEFF-4E70-90CC-1D0B56A8ADF5}" - ProjectSection(ProjectDependencies) = postProject - {5A6656D5-81C7-472C-9DC8-32D071CB2258} = {5A6656D5-81C7-472C-9DC8-32D071CB2258} - EndProjectSection -EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Scalar.Mount.Mac", "Scalar.Mount\Scalar.Mount.Mac.csproj", "{35CA4DFB-1320-4055-B8F6-F12E0F252FF0}" -EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Scalar.FunctionalTests", "Scalar.FunctionalTests\Scalar.FunctionalTests.csproj", "{BD7C5776-82F2-40C6-AF01-B3CC1E2D83AF}" - ProjectSection(ProjectDependencies) = postProject - {17498502-AEFF-4E70-90CC-1D0B56A8ADF5} = {17498502-AEFF-4E70-90CC-1D0B56A8ADF5} - {28939122-7263-41E7-A7E2-CBFB01AD6A04} = {28939122-7263-41E7-A7E2-CBFB01AD6A04} - {32220664-594C-4425-B9A0-88E0BE2F3D2A} = {32220664-594C-4425-B9A0-88E0BE2F3D2A} - {B8C1DFBA-CAFD-4F7E-A1A3-E11907B5467B} = {B8C1DFBA-CAFD-4F7E-A1A3-E11907B5467B} - {35CA4DFB-1320-4055-B8F6-F12E0F252FF0} = {35CA4DFB-1320-4055-B8F6-F12E0F252FF0} - EndProjectSection -EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Scalar.Upgrader", "Scalar.Upgrader\Scalar.Upgrader.csproj", "{AECEC217-2499-403D-B0BB-2962B9BE5970}" -EndProject -Global - GlobalSection(SolutionConfigurationPlatforms) = preSolution - Debug.Mac|x64 = Debug.Mac|x64 - Debug.Windows|x64 = Debug.Windows|x64 - Release.Mac|x64 = Release.Mac|x64 - Release.Windows|x64 = Release.Windows|x64 - EndGlobalSection - GlobalSection(ProjectConfigurationPlatforms) = postSolution - {374BF1E5-0B2D-4D4A-BD5E-4212299DEF09}.Debug.Mac|x64.ActiveCfg = Debug|x64 - {374BF1E5-0B2D-4D4A-BD5E-4212299DEF09}.Debug.Mac|x64.Build.0 = Debug|x64 - {374BF1E5-0B2D-4D4A-BD5E-4212299DEF09}.Debug.Windows|x64.ActiveCfg = Debug|x64 - {374BF1E5-0B2D-4D4A-BD5E-4212299DEF09}.Debug.Windows|x64.Build.0 = Debug|x64 - {374BF1E5-0B2D-4D4A-BD5E-4212299DEF09}.Release.Mac|x64.ActiveCfg = Release|x64 - {374BF1E5-0B2D-4D4A-BD5E-4212299DEF09}.Release.Mac|x64.Build.0 = Release|x64 - {374BF1E5-0B2D-4D4A-BD5E-4212299DEF09}.Release.Windows|x64.ActiveCfg = Release|x64 - {374BF1E5-0B2D-4D4A-BD5E-4212299DEF09}.Release.Windows|x64.Build.0 = Release|x64 - {72701BC3-5DA9-4C7A-BF10-9E98C9FC8EAC}.Debug.Mac|x64.ActiveCfg = Debug|x64 - {72701BC3-5DA9-4C7A-BF10-9E98C9FC8EAC}.Debug.Mac|x64.Build.0 = Debug|x64 - {72701BC3-5DA9-4C7A-BF10-9E98C9FC8EAC}.Debug.Windows|x64.ActiveCfg = Debug|x64 - {72701BC3-5DA9-4C7A-BF10-9E98C9FC8EAC}.Debug.Windows|x64.Build.0 = Debug|x64 - {72701BC3-5DA9-4C7A-BF10-9E98C9FC8EAC}.Release.Mac|x64.ActiveCfg = Release|x64 - {72701BC3-5DA9-4C7A-BF10-9E98C9FC8EAC}.Release.Mac|x64.Build.0 = Release|x64 - {72701BC3-5DA9-4C7A-BF10-9E98C9FC8EAC}.Release.Windows|x64.ActiveCfg = Release|x64 - {72701BC3-5DA9-4C7A-BF10-9E98C9FC8EAC}.Release.Windows|x64.Build.0 = Release|x64 - {8E0D0989-21F6-4DD8-946C-39F992523CC6}.Debug.Mac|x64.ActiveCfg = Debug|x64 - {8E0D0989-21F6-4DD8-946C-39F992523CC6}.Debug.Windows|x64.ActiveCfg = Debug|x64 - {8E0D0989-21F6-4DD8-946C-39F992523CC6}.Debug.Windows|x64.Build.0 = Debug|x64 - {8E0D0989-21F6-4DD8-946C-39F992523CC6}.Release.Mac|x64.ActiveCfg = Release|x64 - {8E0D0989-21F6-4DD8-946C-39F992523CC6}.Release.Windows|x64.ActiveCfg = Release|x64 - {8E0D0989-21F6-4DD8-946C-39F992523CC6}.Release.Windows|x64.Build.0 = Release|x64 - {B8C1DFBA-CAFD-4F7E-A1A3-E11907B5467B}.Debug.Mac|x64.ActiveCfg = Debug|x64 - {B8C1DFBA-CAFD-4F7E-A1A3-E11907B5467B}.Debug.Windows|x64.ActiveCfg = Debug|x64 - {B8C1DFBA-CAFD-4F7E-A1A3-E11907B5467B}.Debug.Windows|x64.Build.0 = Debug|x64 - {B8C1DFBA-CAFD-4F7E-A1A3-E11907B5467B}.Release.Mac|x64.ActiveCfg = Release|x64 - {B8C1DFBA-CAFD-4F7E-A1A3-E11907B5467B}.Release.Windows|x64.ActiveCfg = Release|x64 - {B8C1DFBA-CAFD-4F7E-A1A3-E11907B5467B}.Release.Windows|x64.Build.0 = Release|x64 - {03769A07-F216-456B-886B-E07CAF6C5E81}.Debug.Mac|x64.ActiveCfg = Debug|x64 - {03769A07-F216-456B-886B-E07CAF6C5E81}.Debug.Mac|x64.Build.0 = Debug|x64 - {03769A07-F216-456B-886B-E07CAF6C5E81}.Debug.Windows|x64.ActiveCfg = Debug|x64 - {03769A07-F216-456B-886B-E07CAF6C5E81}.Debug.Windows|x64.Build.0 = Debug|x64 - {03769A07-F216-456B-886B-E07CAF6C5E81}.Release.Mac|x64.ActiveCfg = Release|x64 - {03769A07-F216-456B-886B-E07CAF6C5E81}.Release.Mac|x64.Build.0 = Release|x64 - {03769A07-F216-456B-886B-E07CAF6C5E81}.Release.Windows|x64.ActiveCfg = Release|x64 - {03769A07-F216-456B-886B-E07CAF6C5E81}.Release.Windows|x64.Build.0 = Release|x64 - {5A6656D5-81C7-472C-9DC8-32D071CB2258}.Debug.Mac|x64.ActiveCfg = Debug|x64 - {5A6656D5-81C7-472C-9DC8-32D071CB2258}.Debug.Windows|x64.ActiveCfg = Debug|x64 - {5A6656D5-81C7-472C-9DC8-32D071CB2258}.Debug.Windows|x64.Build.0 = Debug|x64 - {5A6656D5-81C7-472C-9DC8-32D071CB2258}.Release.Mac|x64.ActiveCfg = Release|x64 - {5A6656D5-81C7-472C-9DC8-32D071CB2258}.Release.Windows|x64.ActiveCfg = Release|x64 - {5A6656D5-81C7-472C-9DC8-32D071CB2258}.Release.Windows|x64.Build.0 = Release|x64 - {93B403FD-DAFB-46C5-9636-B122792A548A}.Debug.Mac|x64.ActiveCfg = Debug|x64 - {93B403FD-DAFB-46C5-9636-B122792A548A}.Debug.Windows|x64.ActiveCfg = Debug|x64 - {93B403FD-DAFB-46C5-9636-B122792A548A}.Debug.Windows|x64.Build.0 = Debug|x64 - {93B403FD-DAFB-46C5-9636-B122792A548A}.Release.Mac|x64.ActiveCfg = Release|x64 - {93B403FD-DAFB-46C5-9636-B122792A548A}.Release.Windows|x64.ActiveCfg = Release|x64 - {93B403FD-DAFB-46C5-9636-B122792A548A}.Release.Windows|x64.Build.0 = Release|x64 - {A4984251-840E-4622-AD0C-66DFCE2B2574}.Debug.Mac|x64.ActiveCfg = Debug|x64 - {A4984251-840E-4622-AD0C-66DFCE2B2574}.Debug.Windows|x64.ActiveCfg = Debug|x64 - {A4984251-840E-4622-AD0C-66DFCE2B2574}.Debug.Windows|x64.Build.0 = Debug|x64 - {A4984251-840E-4622-AD0C-66DFCE2B2574}.Release.Mac|x64.ActiveCfg = Release|x64 - {A4984251-840E-4622-AD0C-66DFCE2B2574}.Release.Windows|x64.ActiveCfg = Release|x64 - {A4984251-840E-4622-AD0C-66DFCE2B2574}.Release.Windows|x64.Build.0 = Release|x64 - {3AB4FB1F-9E23-4CD8-BFAC-8A2221C8F893}.Debug.Mac|x64.ActiveCfg = Debug|x64 - {3AB4FB1F-9E23-4CD8-BFAC-8A2221C8F893}.Debug.Windows|x64.ActiveCfg = Debug|x64 - {3AB4FB1F-9E23-4CD8-BFAC-8A2221C8F893}.Debug.Windows|x64.Build.0 = Debug|x64 - {3AB4FB1F-9E23-4CD8-BFAC-8A2221C8F893}.Release.Mac|x64.ActiveCfg = Release|x64 - {3AB4FB1F-9E23-4CD8-BFAC-8A2221C8F893}.Release.Windows|x64.ActiveCfg = Release|x64 - {3AB4FB1F-9E23-4CD8-BFAC-8A2221C8F893}.Release.Windows|x64.Build.0 = Release|x64 - {25229A04-6554-49B1-A95A-3F3B76C5B0C8}.Debug.Mac|x64.ActiveCfg = Debug|x64 - {25229A04-6554-49B1-A95A-3F3B76C5B0C8}.Debug.Mac|x64.Build.0 = Debug|x64 - {25229A04-6554-49B1-A95A-3F3B76C5B0C8}.Debug.Windows|x64.ActiveCfg = Debug|x64 - {25229A04-6554-49B1-A95A-3F3B76C5B0C8}.Release.Mac|x64.ActiveCfg = Release|x64 - {25229A04-6554-49B1-A95A-3F3B76C5B0C8}.Release.Mac|x64.Build.0 = Release|x64 - {25229A04-6554-49B1-A95A-3F3B76C5B0C8}.Release.Windows|x64.ActiveCfg = Release|x64 - {2F63B22B-EE26-4266-BF17-28A9146483A1}.Debug.Mac|x64.ActiveCfg = Debug|x64 - {2F63B22B-EE26-4266-BF17-28A9146483A1}.Debug.Windows|x64.ActiveCfg = Debug|x64 - {2F63B22B-EE26-4266-BF17-28A9146483A1}.Debug.Windows|x64.Build.0 = Debug|x64 - {2F63B22B-EE26-4266-BF17-28A9146483A1}.Release.Mac|x64.ActiveCfg = Release|x64 - {2F63B22B-EE26-4266-BF17-28A9146483A1}.Release.Windows|x64.ActiveCfg = Release|x64 - {2F63B22B-EE26-4266-BF17-28A9146483A1}.Release.Windows|x64.Build.0 = Release|x64 - {1DAC3DA6-3D21-4917-B9A8-D60C8712252A}.Debug.Mac|x64.ActiveCfg = Debug|x64 - {1DAC3DA6-3D21-4917-B9A8-D60C8712252A}.Debug.Mac|x64.Build.0 = Debug|x64 - {1DAC3DA6-3D21-4917-B9A8-D60C8712252A}.Debug.Windows|x64.ActiveCfg = Debug|x64 - {1DAC3DA6-3D21-4917-B9A8-D60C8712252A}.Debug.Windows|x64.Build.0 = Debug|x64 - {1DAC3DA6-3D21-4917-B9A8-D60C8712252A}.Release.Mac|x64.ActiveCfg = Release|x64 - {1DAC3DA6-3D21-4917-B9A8-D60C8712252A}.Release.Mac|x64.Build.0 = Release|x64 - {1DAC3DA6-3D21-4917-B9A8-D60C8712252A}.Release.Windows|x64.ActiveCfg = Release|x64 - {1DAC3DA6-3D21-4917-B9A8-D60C8712252A}.Release.Windows|x64.Build.0 = Release|x64 - {15FAE44C-0D21-4312-9FD3-28F05A5AB7A6}.Debug.Mac|x64.ActiveCfg = Debug|x64 - {15FAE44C-0D21-4312-9FD3-28F05A5AB7A6}.Debug.Mac|x64.Build.0 = Debug|x64 - {15FAE44C-0D21-4312-9FD3-28F05A5AB7A6}.Debug.Windows|x64.ActiveCfg = Debug|x64 - {15FAE44C-0D21-4312-9FD3-28F05A5AB7A6}.Debug.Windows|x64.Build.0 = Debug|x64 - {15FAE44C-0D21-4312-9FD3-28F05A5AB7A6}.Release.Mac|x64.ActiveCfg = Release|x64 - {15FAE44C-0D21-4312-9FD3-28F05A5AB7A6}.Release.Mac|x64.Build.0 = Release|x64 - {15FAE44C-0D21-4312-9FD3-28F05A5AB7A6}.Release.Windows|x64.ActiveCfg = Release|x64 - {15FAE44C-0D21-4312-9FD3-28F05A5AB7A6}.Release.Windows|x64.Build.0 = Release|x64 - {0D434FA7-6D8C-481E-B0CE-779B59EAEF53}.Debug.Mac|x64.ActiveCfg = Debug|x64 - {0D434FA7-6D8C-481E-B0CE-779B59EAEF53}.Debug.Mac|x64.Build.0 = Debug|x64 - {0D434FA7-6D8C-481E-B0CE-779B59EAEF53}.Debug.Windows|x64.ActiveCfg = Debug|x64 - {0D434FA7-6D8C-481E-B0CE-779B59EAEF53}.Debug.Windows|x64.Build.0 = Debug|x64 - {0D434FA7-6D8C-481E-B0CE-779B59EAEF53}.Release.Mac|x64.ActiveCfg = Release|x64 - {0D434FA7-6D8C-481E-B0CE-779B59EAEF53}.Release.Mac|x64.Build.0 = Release|x64 - {0D434FA7-6D8C-481E-B0CE-779B59EAEF53}.Release.Windows|x64.ActiveCfg = Release|x64 - {0D434FA7-6D8C-481E-B0CE-779B59EAEF53}.Release.Windows|x64.Build.0 = Release|x64 - {4CE404E7-D3FC-471C-993C-64615861EA63}.Debug.Mac|x64.ActiveCfg = Debug|x64 - {4CE404E7-D3FC-471C-993C-64615861EA63}.Debug.Windows|x64.ActiveCfg = Debug|x64 - {4CE404E7-D3FC-471C-993C-64615861EA63}.Debug.Windows|x64.Build.0 = Debug|x64 - {4CE404E7-D3FC-471C-993C-64615861EA63}.Release.Mac|x64.ActiveCfg = Release|x64 - {4CE404E7-D3FC-471C-993C-64615861EA63}.Release.Windows|x64.ActiveCfg = Release|x64 - {4CE404E7-D3FC-471C-993C-64615861EA63}.Release.Windows|x64.Build.0 = Release|x64 - {28939122-7263-41E7-A7E2-CBFB01AD6A04}.Debug.Mac|x64.ActiveCfg = Debug|x64 - {28939122-7263-41E7-A7E2-CBFB01AD6A04}.Debug.Mac|x64.Build.0 = Debug|x64 - {28939122-7263-41E7-A7E2-CBFB01AD6A04}.Debug.Windows|x64.ActiveCfg = Debug|x64 - {28939122-7263-41E7-A7E2-CBFB01AD6A04}.Debug.Windows|x64.Build.0 = Debug|x64 - {28939122-7263-41E7-A7E2-CBFB01AD6A04}.Release.Mac|x64.ActiveCfg = Release|x64 - {28939122-7263-41E7-A7E2-CBFB01AD6A04}.Release.Mac|x64.Build.0 = Release|x64 - {28939122-7263-41E7-A7E2-CBFB01AD6A04}.Release.Windows|x64.ActiveCfg = Release|x64 - {28939122-7263-41E7-A7E2-CBFB01AD6A04}.Release.Windows|x64.Build.0 = Release|x64 - {32220664-594C-4425-B9A0-88E0BE2F3D2A}.Debug.Mac|x64.ActiveCfg = Debug|x64 - {32220664-594C-4425-B9A0-88E0BE2F3D2A}.Debug.Windows|x64.ActiveCfg = Debug|x64 - {32220664-594C-4425-B9A0-88E0BE2F3D2A}.Debug.Windows|x64.Build.0 = Debug|x64 - {32220664-594C-4425-B9A0-88E0BE2F3D2A}.Release.Mac|x64.ActiveCfg = Release|x64 - {32220664-594C-4425-B9A0-88E0BE2F3D2A}.Release.Windows|x64.ActiveCfg = Release|x64 - {32220664-594C-4425-B9A0-88E0BE2F3D2A}.Release.Windows|x64.Build.0 = Release|x64 - {17498502-AEFF-4E70-90CC-1D0B56A8ADF5}.Debug.Mac|x64.ActiveCfg = Debug|x64 - {17498502-AEFF-4E70-90CC-1D0B56A8ADF5}.Debug.Windows|x64.ActiveCfg = Debug|x64 - {17498502-AEFF-4E70-90CC-1D0B56A8ADF5}.Debug.Windows|x64.Build.0 = Debug|x64 - {17498502-AEFF-4E70-90CC-1D0B56A8ADF5}.Release.Mac|x64.ActiveCfg = Release|x64 - {17498502-AEFF-4E70-90CC-1D0B56A8ADF5}.Release.Windows|x64.ActiveCfg = Release|x64 - {17498502-AEFF-4E70-90CC-1D0B56A8ADF5}.Release.Windows|x64.Build.0 = Release|x64 - {35CA4DFB-1320-4055-B8F6-F12E0F252FF0}.Debug.Mac|x64.ActiveCfg = Debug|x64 - {35CA4DFB-1320-4055-B8F6-F12E0F252FF0}.Debug.Mac|x64.Build.0 = Debug|x64 - {35CA4DFB-1320-4055-B8F6-F12E0F252FF0}.Debug.Windows|x64.ActiveCfg = Debug|x64 - {35CA4DFB-1320-4055-B8F6-F12E0F252FF0}.Debug.Windows|x64.Build.0 = Debug|x64 - {35CA4DFB-1320-4055-B8F6-F12E0F252FF0}.Release.Mac|x64.ActiveCfg = Release|x64 - {35CA4DFB-1320-4055-B8F6-F12E0F252FF0}.Release.Mac|x64.Build.0 = Release|x64 - {35CA4DFB-1320-4055-B8F6-F12E0F252FF0}.Release.Windows|x64.ActiveCfg = Release|x64 - {35CA4DFB-1320-4055-B8F6-F12E0F252FF0}.Release.Windows|x64.Build.0 = Release|x64 - {BD7C5776-82F2-40C6-AF01-B3CC1E2D83AF}.Debug.Mac|x64.ActiveCfg = Debug|x64 - {BD7C5776-82F2-40C6-AF01-B3CC1E2D83AF}.Debug.Mac|x64.Build.0 = Debug|x64 - {BD7C5776-82F2-40C6-AF01-B3CC1E2D83AF}.Debug.Windows|x64.ActiveCfg = Debug|x64 - {BD7C5776-82F2-40C6-AF01-B3CC1E2D83AF}.Debug.Windows|x64.Build.0 = Debug|x64 - {BD7C5776-82F2-40C6-AF01-B3CC1E2D83AF}.Release.Mac|x64.ActiveCfg = Release|x64 - {BD7C5776-82F2-40C6-AF01-B3CC1E2D83AF}.Release.Mac|x64.Build.0 = Release|x64 - {BD7C5776-82F2-40C6-AF01-B3CC1E2D83AF}.Release.Windows|x64.ActiveCfg = Release|x64 - {BD7C5776-82F2-40C6-AF01-B3CC1E2D83AF}.Release.Windows|x64.Build.0 = Release|x64 - {AECEC217-2499-403D-B0BB-2962B9BE5970}.Debug.Mac|x64.ActiveCfg = Debug|x64 - {AECEC217-2499-403D-B0BB-2962B9BE5970}.Debug.Windows|x64.ActiveCfg = Debug|x64 - {AECEC217-2499-403D-B0BB-2962B9BE5970}.Debug.Windows|x64.Build.0 = Debug|x64 - {AECEC217-2499-403D-B0BB-2962B9BE5970}.Release.Mac|x64.ActiveCfg = Release|x64 - {AECEC217-2499-403D-B0BB-2962B9BE5970}.Release.Windows|x64.ActiveCfg = Release|x64 - {AECEC217-2499-403D-B0BB-2962B9BE5970}.Release.Windows|x64.Build.0 = Release|x64 - {AECEC217-2499-403D-B0BB-2962B9BE5970}.Debug.Mac|x64.Build.0 = Debug|x64 - {AECEC217-2499-403D-B0BB-2962B9BE5970}.Release.Mac|x64.Build.0 = Release|x64 - EndGlobalSection - GlobalSection(SolutionProperties) = preSolution - HideSolutionNode = FALSE - EndGlobalSection - GlobalSection(NestedProjects) = preSolution - {374BF1E5-0B2D-4D4A-BD5E-4212299DEF09} = {2EF2EC94-3A68-4ED7-9A58-B7057ADBA01C} - {72701BC3-5DA9-4C7A-BF10-9E98C9FC8EAC} = {C41F10F9-1163-4CFA-A465-EA728F75E9FA} - {8E0D0989-21F6-4DD8-946C-39F992523CC6} = {C41F10F9-1163-4CFA-A465-EA728F75E9FA} - {B8C1DFBA-CAFD-4F7E-A1A3-E11907B5467B} = {2EF2EC94-3A68-4ED7-9A58-B7057ADBA01C} - {03769A07-F216-456B-886B-E07CAF6C5E81} = {2EF2EC94-3A68-4ED7-9A58-B7057ADBA01C} - {5A6656D5-81C7-472C-9DC8-32D071CB2258} = {2EF2EC94-3A68-4ED7-9A58-B7057ADBA01C} - {28674A4B-1223-4633-A460-C8CC39B09318} = {DCE11095-DA5F-4878-B58D-2702765560F5} - {93B403FD-DAFB-46C5-9636-B122792A548A} = {2EF2EC94-3A68-4ED7-9A58-B7057ADBA01C} - {A4984251-840E-4622-AD0C-66DFCE2B2574} = {AB0D9230-3893-4486-8899-F9C871FB5D5F} - {3AB4FB1F-9E23-4CD8-BFAC-8A2221C8F893} = {2EF2EC94-3A68-4ED7-9A58-B7057ADBA01C} - {25229A04-6554-49B1-A95A-3F3B76C5B0C8} = {2EF2EC94-3A68-4ED7-9A58-B7057ADBA01C} - {2F63B22B-EE26-4266-BF17-28A9146483A1} = {2EF2EC94-3A68-4ED7-9A58-B7057ADBA01C} - {1DAC3DA6-3D21-4917-B9A8-D60C8712252A} = {2EF2EC94-3A68-4ED7-9A58-B7057ADBA01C} - {15FAE44C-0D21-4312-9FD3-28F05A5AB7A6} = {2EF2EC94-3A68-4ED7-9A58-B7057ADBA01C} - {0D434FA7-6D8C-481E-B0CE-779B59EAEF53} = {C41F10F9-1163-4CFA-A465-EA728F75E9FA} - {4CE404E7-D3FC-471C-993C-64615861EA63} = {2EF2EC94-3A68-4ED7-9A58-B7057ADBA01C} - {28939122-7263-41E7-A7E2-CBFB01AD6A04} = {2EF2EC94-3A68-4ED7-9A58-B7057ADBA01C} - {32220664-594C-4425-B9A0-88E0BE2F3D2A} = {2EF2EC94-3A68-4ED7-9A58-B7057ADBA01C} - {17498502-AEFF-4E70-90CC-1D0B56A8ADF5} = {2EF2EC94-3A68-4ED7-9A58-B7057ADBA01C} - {35CA4DFB-1320-4055-B8F6-F12E0F252FF0} = {2EF2EC94-3A68-4ED7-9A58-B7057ADBA01C} - {BD7C5776-82F2-40C6-AF01-B3CC1E2D83AF} = {C41F10F9-1163-4CFA-A465-EA728F75E9FA} - {AECEC217-2499-403D-B0BB-2962B9BE5970} = {2EF2EC94-3A68-4ED7-9A58-B7057ADBA01C} - EndGlobalSection - GlobalSection(ExtensibilityGlobals) = postSolution - SolutionGuid = {A025908B-DAB1-46CB-83A3-56F3B863D8FA} - EndGlobalSection -EndGlobal +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 16 +VisualStudioVersion = 16.0.29306.174 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{DCE11095-DA5F-4878-B58D-2702765560F5}" + ProjectSection(SolutionItems) = preProject + .editorconfig = .editorconfig + .gitattributes = .gitattributes + .gitignore = .gitignore + AuthoringTests.md = AuthoringTests.md + nuget.config = nuget.config + Protocol.md = Protocol.md + Readme.md = Readme.md + EndProjectSection +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Scalar", "Scalar", "{2EF2EC94-3A68-4ED7-9A58-B7057ADBA01C}" + ProjectSection(SolutionItems) = preProject + Scalar.Build\LibGit2Sharp.NativeBinaries.props = Scalar.Build\LibGit2Sharp.NativeBinaries.props + EndProjectSection +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Scalar.Common", "Scalar.Common\Scalar.Common.csproj", "{374BF1E5-0B2D-4D4A-BD5E-4212299DEF09}" + ProjectSection(ProjectDependencies) = postProject + {A4984251-840E-4622-AD0C-66DFCE2B2574} = {A4984251-840E-4622-AD0C-66DFCE2B2574} + EndProjectSection +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Scalar.Tests", "Scalar.Tests\Scalar.Tests.csproj", "{72701BC3-5DA9-4C7A-BF10-9E98C9FC8EAC}" + ProjectSection(ProjectDependencies) = postProject + {A4984251-840E-4622-AD0C-66DFCE2B2574} = {A4984251-840E-4622-AD0C-66DFCE2B2574} + EndProjectSection +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Scalar Tests", "Scalar Tests", "{C41F10F9-1163-4CFA-A465-EA728F75E9FA}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Scalar.UnitTests.Windows", "Scalar.UnitTests.Windows\Scalar.UnitTests.Windows.csproj", "{8E0D0989-21F6-4DD8-946C-39F992523CC6}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Scalar.Service.Windows", "Scalar.Service\Scalar.Service.Windows.csproj", "{B8C1DFBA-CAFD-4F7E-A1A3-E11907B5467B}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Scalar.Service.Mac", "Scalar.Service\Scalar.Service.Mac.csproj", "{03769A07-F216-456B-886B-E07CAF6C5E81}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Scripts", "Scripts", "{28674A4B-1223-4633-A460-C8CC39B09318}" + ProjectSection(SolutionItems) = preProject + Scripts\CreateCommonAssemblyVersion.bat = Scripts\CreateCommonAssemblyVersion.bat + Scripts\CreateCommonCliAssemblyVersion.bat = Scripts\CreateCommonCliAssemblyVersion.bat + Scripts\CreateCommonVersionHeader.bat = Scripts\CreateCommonVersionHeader.bat + Scripts\RunFunctionalTests.bat = Scripts\RunFunctionalTests.bat + Scripts\RunUnitTests.bat = Scripts\RunUnitTests.bat + EndProjectSection +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Scalar.Service.UI", "Scalar.Service.UI\Scalar.Service.UI.csproj", "{93B403FD-DAFB-46C5-9636-B122792A548A}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Scalar.PreBuild", "Scalar.Build\Scalar.PreBuild.csproj", "{A4984251-840E-4622-AD0C-66DFCE2B2574}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Build", "Build", "{AB0D9230-3893-4486-8899-F9C871FB5D5F}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Scalar.Installer.Windows", "Scalar.Installer.Windows\Scalar.Installer.Windows.csproj", "{3AB4FB1F-9E23-4CD8-BFAC-8A2221C8F893}" + ProjectSection(ProjectDependencies) = postProject + {2F63B22B-EE26-4266-BF17-28A9146483A1} = {2F63B22B-EE26-4266-BF17-28A9146483A1} + EndProjectSection +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Scalar.Installer.Mac", "Scalar.Installer.Mac\Scalar.Installer.Mac.csproj", "{25229A04-6554-49B1-A95A-3F3B76C5B0C8}" + ProjectSection(ProjectDependencies) = postProject + {03769A07-F216-456B-886B-E07CAF6C5E81} = {03769A07-F216-456B-886B-E07CAF6C5E81} + {28939122-7263-41E7-A7E2-CBFB01AD6A04} = {28939122-7263-41E7-A7E2-CBFB01AD6A04} + {A4984251-840E-4622-AD0C-66DFCE2B2574} = {A4984251-840E-4622-AD0C-66DFCE2B2574} + {1DAC3DA6-3D21-4917-B9A8-D60C8712252A} = {1DAC3DA6-3D21-4917-B9A8-D60C8712252A} + {374BF1E5-0B2D-4D4A-BD5E-4212299DEF09} = {374BF1E5-0B2D-4D4A-BD5E-4212299DEF09} + {35CA4DFB-1320-4055-B8F6-F12E0F252FF0} = {35CA4DFB-1320-4055-B8F6-F12E0F252FF0} + {AECEC217-2499-403D-B0BB-2962B9BE5970} = {AECEC217-2499-403D-B0BB-2962B9BE5970} + EndProjectSection +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Scalar.SignFiles", "Scalar.SignFiles\Scalar.SignFiles.csproj", "{2F63B22B-EE26-4266-BF17-28A9146483A1}" + ProjectSection(ProjectDependencies) = postProject + {17498502-AEFF-4E70-90CC-1D0B56A8ADF5} = {17498502-AEFF-4E70-90CC-1D0B56A8ADF5} + {32220664-594C-4425-B9A0-88E0BE2F3D2A} = {32220664-594C-4425-B9A0-88E0BE2F3D2A} + {B8C1DFBA-CAFD-4F7E-A1A3-E11907B5467B} = {B8C1DFBA-CAFD-4F7E-A1A3-E11907B5467B} + {374BF1E5-0B2D-4D4A-BD5E-4212299DEF09} = {374BF1E5-0B2D-4D4A-BD5E-4212299DEF09} + {4CE404E7-D3FC-471C-993C-64615861EA63} = {4CE404E7-D3FC-471C-993C-64615861EA63} + {93B403FD-DAFB-46C5-9636-B122792A548A} = {93B403FD-DAFB-46C5-9636-B122792A548A} + {AECEC217-2499-403D-B0BB-2962B9BE5970} = {AECEC217-2499-403D-B0BB-2962B9BE5970} + EndProjectSection +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Scalar.Platform.Mac", "Scalar.Platform.Mac\Scalar.Platform.Mac.csproj", "{1DAC3DA6-3D21-4917-B9A8-D60C8712252A}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Scalar.Platform.POSIX", "Scalar.Platform.POSIX\Scalar.Platform.POSIX.csproj", "{15FAE44C-0D21-4312-9FD3-28F05A5AB7A6}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Scalar.UnitTests", "Scalar.UnitTests\Scalar.UnitTests.csproj", "{0D434FA7-6D8C-481E-B0CE-779B59EAEF53}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Scalar.Platform.Windows", "Scalar.Platform.Windows\Scalar.Platform.Windows.csproj", "{4CE404E7-D3FC-471C-993C-64615861EA63}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Scalar.Mac", "Scalar\Scalar.Mac.csproj", "{28939122-7263-41E7-A7E2-CBFB01AD6A04}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Scalar.Windows", "Scalar\Scalar.Windows.csproj", "{32220664-594C-4425-B9A0-88E0BE2F3D2A}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Scalar.Mount.Windows", "Scalar.Mount\Scalar.Mount.Windows.csproj", "{17498502-AEFF-4E70-90CC-1D0B56A8ADF5}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Scalar.Mount.Mac", "Scalar.Mount\Scalar.Mount.Mac.csproj", "{35CA4DFB-1320-4055-B8F6-F12E0F252FF0}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Scalar.FunctionalTests", "Scalar.FunctionalTests\Scalar.FunctionalTests.csproj", "{BD7C5776-82F2-40C6-AF01-B3CC1E2D83AF}" + ProjectSection(ProjectDependencies) = postProject + {17498502-AEFF-4E70-90CC-1D0B56A8ADF5} = {17498502-AEFF-4E70-90CC-1D0B56A8ADF5} + {28939122-7263-41E7-A7E2-CBFB01AD6A04} = {28939122-7263-41E7-A7E2-CBFB01AD6A04} + {32220664-594C-4425-B9A0-88E0BE2F3D2A} = {32220664-594C-4425-B9A0-88E0BE2F3D2A} + {B8C1DFBA-CAFD-4F7E-A1A3-E11907B5467B} = {B8C1DFBA-CAFD-4F7E-A1A3-E11907B5467B} + {35CA4DFB-1320-4055-B8F6-F12E0F252FF0} = {35CA4DFB-1320-4055-B8F6-F12E0F252FF0} + EndProjectSection +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Scalar.Upgrader", "Scalar.Upgrader\Scalar.Upgrader.csproj", "{AECEC217-2499-403D-B0BB-2962B9BE5970}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug.Mac|x64 = Debug.Mac|x64 + Debug.Windows|x64 = Debug.Windows|x64 + Release.Mac|x64 = Release.Mac|x64 + Release.Windows|x64 = Release.Windows|x64 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {374BF1E5-0B2D-4D4A-BD5E-4212299DEF09}.Debug.Mac|x64.ActiveCfg = Debug|x64 + {374BF1E5-0B2D-4D4A-BD5E-4212299DEF09}.Debug.Mac|x64.Build.0 = Debug|x64 + {374BF1E5-0B2D-4D4A-BD5E-4212299DEF09}.Debug.Windows|x64.ActiveCfg = Debug|x64 + {374BF1E5-0B2D-4D4A-BD5E-4212299DEF09}.Debug.Windows|x64.Build.0 = Debug|x64 + {374BF1E5-0B2D-4D4A-BD5E-4212299DEF09}.Release.Mac|x64.ActiveCfg = Release|x64 + {374BF1E5-0B2D-4D4A-BD5E-4212299DEF09}.Release.Mac|x64.Build.0 = Release|x64 + {374BF1E5-0B2D-4D4A-BD5E-4212299DEF09}.Release.Windows|x64.ActiveCfg = Release|x64 + {374BF1E5-0B2D-4D4A-BD5E-4212299DEF09}.Release.Windows|x64.Build.0 = Release|x64 + {72701BC3-5DA9-4C7A-BF10-9E98C9FC8EAC}.Debug.Mac|x64.ActiveCfg = Debug|x64 + {72701BC3-5DA9-4C7A-BF10-9E98C9FC8EAC}.Debug.Mac|x64.Build.0 = Debug|x64 + {72701BC3-5DA9-4C7A-BF10-9E98C9FC8EAC}.Debug.Windows|x64.ActiveCfg = Debug|x64 + {72701BC3-5DA9-4C7A-BF10-9E98C9FC8EAC}.Debug.Windows|x64.Build.0 = Debug|x64 + {72701BC3-5DA9-4C7A-BF10-9E98C9FC8EAC}.Release.Mac|x64.ActiveCfg = Release|x64 + {72701BC3-5DA9-4C7A-BF10-9E98C9FC8EAC}.Release.Mac|x64.Build.0 = Release|x64 + {72701BC3-5DA9-4C7A-BF10-9E98C9FC8EAC}.Release.Windows|x64.ActiveCfg = Release|x64 + {72701BC3-5DA9-4C7A-BF10-9E98C9FC8EAC}.Release.Windows|x64.Build.0 = Release|x64 + {8E0D0989-21F6-4DD8-946C-39F992523CC6}.Debug.Mac|x64.ActiveCfg = Debug|x64 + {8E0D0989-21F6-4DD8-946C-39F992523CC6}.Debug.Windows|x64.ActiveCfg = Debug|x64 + {8E0D0989-21F6-4DD8-946C-39F992523CC6}.Debug.Windows|x64.Build.0 = Debug|x64 + {8E0D0989-21F6-4DD8-946C-39F992523CC6}.Release.Mac|x64.ActiveCfg = Release|x64 + {8E0D0989-21F6-4DD8-946C-39F992523CC6}.Release.Windows|x64.ActiveCfg = Release|x64 + {8E0D0989-21F6-4DD8-946C-39F992523CC6}.Release.Windows|x64.Build.0 = Release|x64 + {B8C1DFBA-CAFD-4F7E-A1A3-E11907B5467B}.Debug.Mac|x64.ActiveCfg = Debug|x64 + {B8C1DFBA-CAFD-4F7E-A1A3-E11907B5467B}.Debug.Windows|x64.ActiveCfg = Debug|x64 + {B8C1DFBA-CAFD-4F7E-A1A3-E11907B5467B}.Debug.Windows|x64.Build.0 = Debug|x64 + {B8C1DFBA-CAFD-4F7E-A1A3-E11907B5467B}.Release.Mac|x64.ActiveCfg = Release|x64 + {B8C1DFBA-CAFD-4F7E-A1A3-E11907B5467B}.Release.Windows|x64.ActiveCfg = Release|x64 + {B8C1DFBA-CAFD-4F7E-A1A3-E11907B5467B}.Release.Windows|x64.Build.0 = Release|x64 + {03769A07-F216-456B-886B-E07CAF6C5E81}.Debug.Mac|x64.ActiveCfg = Debug|x64 + {03769A07-F216-456B-886B-E07CAF6C5E81}.Debug.Mac|x64.Build.0 = Debug|x64 + {03769A07-F216-456B-886B-E07CAF6C5E81}.Debug.Windows|x64.ActiveCfg = Debug|x64 + {03769A07-F216-456B-886B-E07CAF6C5E81}.Debug.Windows|x64.Build.0 = Debug|x64 + {03769A07-F216-456B-886B-E07CAF6C5E81}.Release.Mac|x64.ActiveCfg = Release|x64 + {03769A07-F216-456B-886B-E07CAF6C5E81}.Release.Mac|x64.Build.0 = Release|x64 + {03769A07-F216-456B-886B-E07CAF6C5E81}.Release.Windows|x64.ActiveCfg = Release|x64 + {03769A07-F216-456B-886B-E07CAF6C5E81}.Release.Windows|x64.Build.0 = Release|x64 + {93B403FD-DAFB-46C5-9636-B122792A548A}.Debug.Mac|x64.ActiveCfg = Debug|x64 + {93B403FD-DAFB-46C5-9636-B122792A548A}.Debug.Windows|x64.ActiveCfg = Debug|x64 + {93B403FD-DAFB-46C5-9636-B122792A548A}.Debug.Windows|x64.Build.0 = Debug|x64 + {93B403FD-DAFB-46C5-9636-B122792A548A}.Release.Mac|x64.ActiveCfg = Release|x64 + {93B403FD-DAFB-46C5-9636-B122792A548A}.Release.Windows|x64.ActiveCfg = Release|x64 + {93B403FD-DAFB-46C5-9636-B122792A548A}.Release.Windows|x64.Build.0 = Release|x64 + {A4984251-840E-4622-AD0C-66DFCE2B2574}.Debug.Mac|x64.ActiveCfg = Debug|x64 + {A4984251-840E-4622-AD0C-66DFCE2B2574}.Debug.Windows|x64.ActiveCfg = Debug|x64 + {A4984251-840E-4622-AD0C-66DFCE2B2574}.Debug.Windows|x64.Build.0 = Debug|x64 + {A4984251-840E-4622-AD0C-66DFCE2B2574}.Release.Mac|x64.ActiveCfg = Release|x64 + {A4984251-840E-4622-AD0C-66DFCE2B2574}.Release.Windows|x64.ActiveCfg = Release|x64 + {A4984251-840E-4622-AD0C-66DFCE2B2574}.Release.Windows|x64.Build.0 = Release|x64 + {3AB4FB1F-9E23-4CD8-BFAC-8A2221C8F893}.Debug.Mac|x64.ActiveCfg = Debug|x64 + {3AB4FB1F-9E23-4CD8-BFAC-8A2221C8F893}.Debug.Windows|x64.ActiveCfg = Debug|x64 + {3AB4FB1F-9E23-4CD8-BFAC-8A2221C8F893}.Debug.Windows|x64.Build.0 = Debug|x64 + {3AB4FB1F-9E23-4CD8-BFAC-8A2221C8F893}.Release.Mac|x64.ActiveCfg = Release|x64 + {3AB4FB1F-9E23-4CD8-BFAC-8A2221C8F893}.Release.Windows|x64.ActiveCfg = Release|x64 + {3AB4FB1F-9E23-4CD8-BFAC-8A2221C8F893}.Release.Windows|x64.Build.0 = Release|x64 + {25229A04-6554-49B1-A95A-3F3B76C5B0C8}.Debug.Mac|x64.ActiveCfg = Debug|x64 + {25229A04-6554-49B1-A95A-3F3B76C5B0C8}.Debug.Mac|x64.Build.0 = Debug|x64 + {25229A04-6554-49B1-A95A-3F3B76C5B0C8}.Debug.Windows|x64.ActiveCfg = Debug|x64 + {25229A04-6554-49B1-A95A-3F3B76C5B0C8}.Release.Mac|x64.ActiveCfg = Release|x64 + {25229A04-6554-49B1-A95A-3F3B76C5B0C8}.Release.Mac|x64.Build.0 = Release|x64 + {25229A04-6554-49B1-A95A-3F3B76C5B0C8}.Release.Windows|x64.ActiveCfg = Release|x64 + {2F63B22B-EE26-4266-BF17-28A9146483A1}.Debug.Mac|x64.ActiveCfg = Debug|x64 + {2F63B22B-EE26-4266-BF17-28A9146483A1}.Debug.Windows|x64.ActiveCfg = Debug|x64 + {2F63B22B-EE26-4266-BF17-28A9146483A1}.Debug.Windows|x64.Build.0 = Debug|x64 + {2F63B22B-EE26-4266-BF17-28A9146483A1}.Release.Mac|x64.ActiveCfg = Release|x64 + {2F63B22B-EE26-4266-BF17-28A9146483A1}.Release.Windows|x64.ActiveCfg = Release|x64 + {2F63B22B-EE26-4266-BF17-28A9146483A1}.Release.Windows|x64.Build.0 = Release|x64 + {1DAC3DA6-3D21-4917-B9A8-D60C8712252A}.Debug.Mac|x64.ActiveCfg = Debug|x64 + {1DAC3DA6-3D21-4917-B9A8-D60C8712252A}.Debug.Mac|x64.Build.0 = Debug|x64 + {1DAC3DA6-3D21-4917-B9A8-D60C8712252A}.Debug.Windows|x64.ActiveCfg = Debug|x64 + {1DAC3DA6-3D21-4917-B9A8-D60C8712252A}.Debug.Windows|x64.Build.0 = Debug|x64 + {1DAC3DA6-3D21-4917-B9A8-D60C8712252A}.Release.Mac|x64.ActiveCfg = Release|x64 + {1DAC3DA6-3D21-4917-B9A8-D60C8712252A}.Release.Mac|x64.Build.0 = Release|x64 + {1DAC3DA6-3D21-4917-B9A8-D60C8712252A}.Release.Windows|x64.ActiveCfg = Release|x64 + {1DAC3DA6-3D21-4917-B9A8-D60C8712252A}.Release.Windows|x64.Build.0 = Release|x64 + {15FAE44C-0D21-4312-9FD3-28F05A5AB7A6}.Debug.Mac|x64.ActiveCfg = Debug|x64 + {15FAE44C-0D21-4312-9FD3-28F05A5AB7A6}.Debug.Mac|x64.Build.0 = Debug|x64 + {15FAE44C-0D21-4312-9FD3-28F05A5AB7A6}.Debug.Windows|x64.ActiveCfg = Debug|x64 + {15FAE44C-0D21-4312-9FD3-28F05A5AB7A6}.Debug.Windows|x64.Build.0 = Debug|x64 + {15FAE44C-0D21-4312-9FD3-28F05A5AB7A6}.Release.Mac|x64.ActiveCfg = Release|x64 + {15FAE44C-0D21-4312-9FD3-28F05A5AB7A6}.Release.Mac|x64.Build.0 = Release|x64 + {15FAE44C-0D21-4312-9FD3-28F05A5AB7A6}.Release.Windows|x64.ActiveCfg = Release|x64 + {15FAE44C-0D21-4312-9FD3-28F05A5AB7A6}.Release.Windows|x64.Build.0 = Release|x64 + {0D434FA7-6D8C-481E-B0CE-779B59EAEF53}.Debug.Mac|x64.ActiveCfg = Debug|x64 + {0D434FA7-6D8C-481E-B0CE-779B59EAEF53}.Debug.Mac|x64.Build.0 = Debug|x64 + {0D434FA7-6D8C-481E-B0CE-779B59EAEF53}.Debug.Windows|x64.ActiveCfg = Debug|x64 + {0D434FA7-6D8C-481E-B0CE-779B59EAEF53}.Debug.Windows|x64.Build.0 = Debug|x64 + {0D434FA7-6D8C-481E-B0CE-779B59EAEF53}.Release.Mac|x64.ActiveCfg = Release|x64 + {0D434FA7-6D8C-481E-B0CE-779B59EAEF53}.Release.Mac|x64.Build.0 = Release|x64 + {0D434FA7-6D8C-481E-B0CE-779B59EAEF53}.Release.Windows|x64.ActiveCfg = Release|x64 + {0D434FA7-6D8C-481E-B0CE-779B59EAEF53}.Release.Windows|x64.Build.0 = Release|x64 + {4CE404E7-D3FC-471C-993C-64615861EA63}.Debug.Mac|x64.ActiveCfg = Debug|x64 + {4CE404E7-D3FC-471C-993C-64615861EA63}.Debug.Windows|x64.ActiveCfg = Debug|x64 + {4CE404E7-D3FC-471C-993C-64615861EA63}.Debug.Windows|x64.Build.0 = Debug|x64 + {4CE404E7-D3FC-471C-993C-64615861EA63}.Release.Mac|x64.ActiveCfg = Release|x64 + {4CE404E7-D3FC-471C-993C-64615861EA63}.Release.Windows|x64.ActiveCfg = Release|x64 + {4CE404E7-D3FC-471C-993C-64615861EA63}.Release.Windows|x64.Build.0 = Release|x64 + {28939122-7263-41E7-A7E2-CBFB01AD6A04}.Debug.Mac|x64.ActiveCfg = Debug|x64 + {28939122-7263-41E7-A7E2-CBFB01AD6A04}.Debug.Mac|x64.Build.0 = Debug|x64 + {28939122-7263-41E7-A7E2-CBFB01AD6A04}.Debug.Windows|x64.ActiveCfg = Debug|x64 + {28939122-7263-41E7-A7E2-CBFB01AD6A04}.Debug.Windows|x64.Build.0 = Debug|x64 + {28939122-7263-41E7-A7E2-CBFB01AD6A04}.Release.Mac|x64.ActiveCfg = Release|x64 + {28939122-7263-41E7-A7E2-CBFB01AD6A04}.Release.Mac|x64.Build.0 = Release|x64 + {28939122-7263-41E7-A7E2-CBFB01AD6A04}.Release.Windows|x64.ActiveCfg = Release|x64 + {28939122-7263-41E7-A7E2-CBFB01AD6A04}.Release.Windows|x64.Build.0 = Release|x64 + {32220664-594C-4425-B9A0-88E0BE2F3D2A}.Debug.Mac|x64.ActiveCfg = Debug|x64 + {32220664-594C-4425-B9A0-88E0BE2F3D2A}.Debug.Windows|x64.ActiveCfg = Debug|x64 + {32220664-594C-4425-B9A0-88E0BE2F3D2A}.Debug.Windows|x64.Build.0 = Debug|x64 + {32220664-594C-4425-B9A0-88E0BE2F3D2A}.Release.Mac|x64.ActiveCfg = Release|x64 + {32220664-594C-4425-B9A0-88E0BE2F3D2A}.Release.Windows|x64.ActiveCfg = Release|x64 + {32220664-594C-4425-B9A0-88E0BE2F3D2A}.Release.Windows|x64.Build.0 = Release|x64 + {17498502-AEFF-4E70-90CC-1D0B56A8ADF5}.Debug.Mac|x64.ActiveCfg = Debug|x64 + {17498502-AEFF-4E70-90CC-1D0B56A8ADF5}.Debug.Windows|x64.ActiveCfg = Debug|x64 + {17498502-AEFF-4E70-90CC-1D0B56A8ADF5}.Debug.Windows|x64.Build.0 = Debug|x64 + {17498502-AEFF-4E70-90CC-1D0B56A8ADF5}.Release.Mac|x64.ActiveCfg = Release|x64 + {17498502-AEFF-4E70-90CC-1D0B56A8ADF5}.Release.Windows|x64.ActiveCfg = Release|x64 + {17498502-AEFF-4E70-90CC-1D0B56A8ADF5}.Release.Windows|x64.Build.0 = Release|x64 + {35CA4DFB-1320-4055-B8F6-F12E0F252FF0}.Debug.Mac|x64.ActiveCfg = Debug|x64 + {35CA4DFB-1320-4055-B8F6-F12E0F252FF0}.Debug.Mac|x64.Build.0 = Debug|x64 + {35CA4DFB-1320-4055-B8F6-F12E0F252FF0}.Debug.Windows|x64.ActiveCfg = Debug|x64 + {35CA4DFB-1320-4055-B8F6-F12E0F252FF0}.Debug.Windows|x64.Build.0 = Debug|x64 + {35CA4DFB-1320-4055-B8F6-F12E0F252FF0}.Release.Mac|x64.ActiveCfg = Release|x64 + {35CA4DFB-1320-4055-B8F6-F12E0F252FF0}.Release.Mac|x64.Build.0 = Release|x64 + {35CA4DFB-1320-4055-B8F6-F12E0F252FF0}.Release.Windows|x64.ActiveCfg = Release|x64 + {35CA4DFB-1320-4055-B8F6-F12E0F252FF0}.Release.Windows|x64.Build.0 = Release|x64 + {BD7C5776-82F2-40C6-AF01-B3CC1E2D83AF}.Debug.Mac|x64.ActiveCfg = Debug|x64 + {BD7C5776-82F2-40C6-AF01-B3CC1E2D83AF}.Debug.Mac|x64.Build.0 = Debug|x64 + {BD7C5776-82F2-40C6-AF01-B3CC1E2D83AF}.Debug.Windows|x64.ActiveCfg = Debug|x64 + {BD7C5776-82F2-40C6-AF01-B3CC1E2D83AF}.Debug.Windows|x64.Build.0 = Debug|x64 + {BD7C5776-82F2-40C6-AF01-B3CC1E2D83AF}.Release.Mac|x64.ActiveCfg = Release|x64 + {BD7C5776-82F2-40C6-AF01-B3CC1E2D83AF}.Release.Mac|x64.Build.0 = Release|x64 + {BD7C5776-82F2-40C6-AF01-B3CC1E2D83AF}.Release.Windows|x64.ActiveCfg = Release|x64 + {BD7C5776-82F2-40C6-AF01-B3CC1E2D83AF}.Release.Windows|x64.Build.0 = Release|x64 + {AECEC217-2499-403D-B0BB-2962B9BE5970}.Debug.Mac|x64.ActiveCfg = Debug|x64 + {AECEC217-2499-403D-B0BB-2962B9BE5970}.Debug.Mac|x64.Build.0 = Debug|x64 + {AECEC217-2499-403D-B0BB-2962B9BE5970}.Debug.Windows|x64.ActiveCfg = Debug|x64 + {AECEC217-2499-403D-B0BB-2962B9BE5970}.Debug.Windows|x64.Build.0 = Debug|x64 + {AECEC217-2499-403D-B0BB-2962B9BE5970}.Release.Mac|x64.ActiveCfg = Release|x64 + {AECEC217-2499-403D-B0BB-2962B9BE5970}.Release.Mac|x64.Build.0 = Release|x64 + {AECEC217-2499-403D-B0BB-2962B9BE5970}.Release.Windows|x64.ActiveCfg = Release|x64 + {AECEC217-2499-403D-B0BB-2962B9BE5970}.Release.Windows|x64.Build.0 = Release|x64 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(NestedProjects) = preSolution + {374BF1E5-0B2D-4D4A-BD5E-4212299DEF09} = {2EF2EC94-3A68-4ED7-9A58-B7057ADBA01C} + {72701BC3-5DA9-4C7A-BF10-9E98C9FC8EAC} = {C41F10F9-1163-4CFA-A465-EA728F75E9FA} + {8E0D0989-21F6-4DD8-946C-39F992523CC6} = {C41F10F9-1163-4CFA-A465-EA728F75E9FA} + {B8C1DFBA-CAFD-4F7E-A1A3-E11907B5467B} = {2EF2EC94-3A68-4ED7-9A58-B7057ADBA01C} + {03769A07-F216-456B-886B-E07CAF6C5E81} = {2EF2EC94-3A68-4ED7-9A58-B7057ADBA01C} + {28674A4B-1223-4633-A460-C8CC39B09318} = {DCE11095-DA5F-4878-B58D-2702765560F5} + {93B403FD-DAFB-46C5-9636-B122792A548A} = {2EF2EC94-3A68-4ED7-9A58-B7057ADBA01C} + {A4984251-840E-4622-AD0C-66DFCE2B2574} = {AB0D9230-3893-4486-8899-F9C871FB5D5F} + {3AB4FB1F-9E23-4CD8-BFAC-8A2221C8F893} = {2EF2EC94-3A68-4ED7-9A58-B7057ADBA01C} + {25229A04-6554-49B1-A95A-3F3B76C5B0C8} = {2EF2EC94-3A68-4ED7-9A58-B7057ADBA01C} + {2F63B22B-EE26-4266-BF17-28A9146483A1} = {2EF2EC94-3A68-4ED7-9A58-B7057ADBA01C} + {1DAC3DA6-3D21-4917-B9A8-D60C8712252A} = {2EF2EC94-3A68-4ED7-9A58-B7057ADBA01C} + {15FAE44C-0D21-4312-9FD3-28F05A5AB7A6} = {2EF2EC94-3A68-4ED7-9A58-B7057ADBA01C} + {0D434FA7-6D8C-481E-B0CE-779B59EAEF53} = {C41F10F9-1163-4CFA-A465-EA728F75E9FA} + {4CE404E7-D3FC-471C-993C-64615861EA63} = {2EF2EC94-3A68-4ED7-9A58-B7057ADBA01C} + {28939122-7263-41E7-A7E2-CBFB01AD6A04} = {2EF2EC94-3A68-4ED7-9A58-B7057ADBA01C} + {32220664-594C-4425-B9A0-88E0BE2F3D2A} = {2EF2EC94-3A68-4ED7-9A58-B7057ADBA01C} + {17498502-AEFF-4E70-90CC-1D0B56A8ADF5} = {2EF2EC94-3A68-4ED7-9A58-B7057ADBA01C} + {35CA4DFB-1320-4055-B8F6-F12E0F252FF0} = {2EF2EC94-3A68-4ED7-9A58-B7057ADBA01C} + {BD7C5776-82F2-40C6-AF01-B3CC1E2D83AF} = {C41F10F9-1163-4CFA-A465-EA728F75E9FA} + {AECEC217-2499-403D-B0BB-2962B9BE5970} = {2EF2EC94-3A68-4ED7-9A58-B7057ADBA01C} + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {A025908B-DAB1-46CB-83A3-56F3B863D8FA} + EndGlobalSection +EndGlobal diff --git a/Scalar/CommandLine/CloneVerb.cs b/Scalar/CommandLine/CloneVerb.cs index 1f1d81dbcf..5788af2b4c 100644 --- a/Scalar/CommandLine/CloneVerb.cs +++ b/Scalar/CommandLine/CloneVerb.cs @@ -3,10 +3,8 @@ using Scalar.Common.FileSystem; using Scalar.Common.Git; using Scalar.Common.Http; -using Scalar.Common.Prefetch; using Scalar.Common.Tracing; using System; -using System.Collections.Generic; using System.Diagnostics; using System.IO; using System.Linq; @@ -570,13 +568,6 @@ private Result CreateClone() return new Result(errorMessage); } - string installHooksError; - if (!HooksInstaller.InstallHooks(this.context, out installHooksError)) - { - this.tracer.RelatedError(installHooksError); - return new Result(installHooksError); - } - if (!RepoMetadata.TryInitialize(this.tracer, this.enlistment.DotScalarRoot, out errorMessage)) { this.tracer.RelatedError(errorMessage); @@ -640,31 +631,6 @@ private Result TryInitRepo() private Result CheckoutRepo() { - if (this.FullClone) - { - BlobPrefetcher prefetcher = new BlobPrefetcher( - this.tracer, - this.enlistment, - this.objectRequestor, - fileList: new List() { "*" }, - folderList: null, - lastPrefetchArgs: null, - chunkSize: 4000, - searchThreadCount: Environment.ProcessorCount, - downloadThreadCount: Environment.ProcessorCount, - indexThreadCount: Environment.ProcessorCount); - prefetcher.PrefetchWithStats( - this.Branch, - isBranch: true, - matchedBlobCount: out int _, - downloadedBlobCount: out int _); - - if (prefetcher.HasFailures) - { - return new Result("Failures while prefetching blobs"); - } - } - GitProcess.Result result = this.git.ForceCheckout(this.Branch); if (result.ExitCodeIsFailure) { diff --git a/Scalar/CommandLine/MountVerb.cs b/Scalar/CommandLine/MountVerb.cs index 0bb39bd0fb..adc196de79 100644 --- a/Scalar/CommandLine/MountVerb.cs +++ b/Scalar/CommandLine/MountVerb.cs @@ -87,11 +87,6 @@ protected override void Execute(ScalarEnlistment enlistment) GitRepo gitRepo = new GitRepo(tracer, enlistment, fileSystem); ScalarContext context = new ScalarContext(tracer, fileSystem, gitRepo, enlistment); - if (!HooksInstaller.InstallHooks(context, out errorMessage)) - { - this.ReportErrorAndExit("Error installing hooks: " + errorMessage); - } - CacheServerInfo cacheServer = this.ResolvedCacheServer ?? CacheServerResolver.GetCacheServerFromConfig(enlistment); tracer.AddLogFileEventListener( diff --git a/Scalar/CommandLine/PrefetchVerb.cs b/Scalar/CommandLine/PrefetchVerb.cs index c13dcddc75..b3a77348d5 100644 --- a/Scalar/CommandLine/PrefetchVerb.cs +++ b/Scalar/CommandLine/PrefetchVerb.cs @@ -4,11 +4,8 @@ using Scalar.Common.Git; using Scalar.Common.Http; using Scalar.Common.Maintenance; -using Scalar.Common.Prefetch; using Scalar.Common.Tracing; using System; -using System.Collections.Generic; -using System.IO; namespace Scalar.CommandLine { @@ -17,65 +14,14 @@ public class PrefetchVerb : ScalarVerb.ForExistingEnlistment { private const string PrefetchVerbName = "prefetch"; - private const int LockWaitTimeMs = 100; - private const int WaitingOnLockLogThreshold = 50; - private const int IoFailureRetryDelayMS = 50; - private const string PrefetchCommitsAndTreesLock = "prefetch-commits-trees.lock"; - - private const int ChunkSize = 4000; - private static readonly int SearchThreadCount = Environment.ProcessorCount; - private static readonly int DownloadThreadCount = Environment.ProcessorCount; - private static readonly int IndexThreadCount = Environment.ProcessorCount; - - private List parsedFoldersList; - - [Option( - "files", - Required = false, - Default = "", - HelpText = "A semicolon-delimited list of files to fetch. Simple prefix wildcards, e.g. *.txt, are supported.")] - public string Files { get; set; } - - [Option( - "folders", - Required = false, - Default = "", - HelpText = "A semicolon-delimited list of folders to fetch. Wildcards are not supported.")] - public string Folders { get; set; } - - [Option( - "folders-list", - Required = false, - Default = "", - HelpText = "A file containing line-delimited list of folders to fetch. Wildcards are not supported.")] - public string FoldersListFile { get; set; } - - [Option( - "stdin-files-list", - Required = false, - Default = false, - HelpText = "Specify this flag to load file list from stdin. Same format as when loading from file.")] - public bool FilesFromStdIn { get; set; } - - [Option( - "stdin-folders-list", - Required = false, - Default = false, - HelpText = "Specify this flag to load folder list from stdin. Same format as when loading from file.")] - public bool FoldersFromStdIn { get; set; } - - [Option( - "files-list", - Required = false, - Default = "", - HelpText = "A file containing line-delimited list of files to fetch. Wildcards are supported.")] - public string FilesListFile { get; set; } - + /// + /// This does not change behavior, but we leave it here as it is called by a hook this way. + /// [Option( 'c', "commits", Required = false, - Default = false, + Default = true, HelpText = "Fetch the latest set of commit and tree packs. This option cannot be used with any of the file- or folder-related options.")] public bool Commits { get; set; } @@ -90,11 +36,6 @@ public class PrefetchVerb : ScalarVerb.ForExistingEnlistment public CacheServerInfo ResolvedCacheServer { get; set; } public ServerScalarConfig ServerScalarConfig { get; set; } - public List ParsedFoldersList - { - get { return this.parsedFoldersList; } - } - protected override string VerbName { get { return PrefetchVerbName; } @@ -124,61 +65,17 @@ protected override void Execute(ScalarEnlistment enlistment) { EventMetadata metadata = new EventMetadata(); metadata.Add("Commits", this.Commits); - metadata.Add("Files", this.Files); - metadata.Add("Folders", this.Folders); - metadata.Add("FileListFile", this.FilesListFile); - metadata.Add("FoldersListFile", this.FoldersListFile); - metadata.Add("FilesFromStdIn", this.FilesFromStdIn); - metadata.Add("FoldersFromStdIn", this.FoldersFromStdIn); tracer.RelatedEvent(EventLevel.Informational, "PerformPrefetch", metadata); - if (this.Commits) - { - if (!string.IsNullOrWhiteSpace(this.Files) || - !string.IsNullOrWhiteSpace(this.Folders) || - !string.IsNullOrWhiteSpace(this.FoldersListFile) || - !string.IsNullOrWhiteSpace(this.FilesListFile) || - this.FilesFromStdIn || - this.FoldersFromStdIn) - { - this.ReportErrorAndExit(tracer, "You cannot prefetch commits and blobs at the same time."); - } - - GitObjectsHttpRequestor objectRequestor; - CacheServerInfo cacheServer; - this.InitializeServerConnection( - tracer, - enlistment, - cacheServerUrl, - out objectRequestor, - out cacheServer); - this.PrefetchCommits(tracer, enlistment, objectRequestor, cacheServer); - } - else - { - string headCommitId; - List filesList; - FileBasedDictionary lastPrefetchArgs; - - this.LoadBlobPrefetchArgs(tracer, enlistment, out headCommitId, out filesList, out this.parsedFoldersList, out lastPrefetchArgs); - - if (BlobPrefetcher.IsNoopPrefetch(tracer, lastPrefetchArgs, headCommitId, filesList, this.parsedFoldersList)) - { - Console.WriteLine("All requested files are already available. Nothing new to prefetch."); - } - else - { - GitObjectsHttpRequestor objectRequestor; - CacheServerInfo cacheServer; - this.InitializeServerConnection( - tracer, - enlistment, - cacheServerUrl, - out objectRequestor, - out cacheServer); - this.PrefetchBlobs(tracer, enlistment, headCommitId, filesList, this.parsedFoldersList, lastPrefetchArgs, objectRequestor, cacheServer); - } - } + GitObjectsHttpRequestor objectRequestor; + CacheServerInfo cacheServer; + this.InitializeServerConnection( + tracer, + enlistment, + cacheServerUrl, + out objectRequestor, + out cacheServer); + this.PrefetchCommits(tracer, enlistment, objectRequestor, cacheServer); } catch (VerbAbortedException) { @@ -285,143 +182,6 @@ private void PrefetchCommits(ITracer tracer, ScalarEnlistment enlistment, GitObj } } - private void LoadBlobPrefetchArgs( - ITracer tracer, - ScalarEnlistment enlistment, - out string headCommitId, - out List filesList, - out List foldersList, - out FileBasedDictionary lastPrefetchArgs) - { - string error; - - if (!FileBasedDictionary.TryCreate( - tracer, - Path.Combine(enlistment.DotScalarRoot, "LastBlobPrefetch.dat"), - new PhysicalFileSystem(), - out lastPrefetchArgs, - out error)) - { - tracer.RelatedWarning("Unable to load last prefetch args: " + error); - } - - filesList = new List(); - foldersList = new List(); - - if (!BlobPrefetcher.TryLoadFileList(enlistment, this.Files, this.FilesListFile, filesList, readListFromStdIn: this.FilesFromStdIn, error: out error)) - { - this.ReportErrorAndExit(tracer, error); - } - - if (!BlobPrefetcher.TryLoadFolderList(enlistment, this.Folders, this.FoldersListFile, foldersList, readListFromStdIn: this.FoldersFromStdIn, error: out error)) - { - this.ReportErrorAndExit(tracer, error); - } - - GitProcess gitProcess = new GitProcess(enlistment); - GitProcess.Result result = gitProcess.RevParse(ScalarConstants.DotGit.HeadName); - if (result.ExitCodeIsFailure) - { - this.ReportErrorAndExit(tracer, result.Errors); - } - - headCommitId = result.Output.Trim(); - } - - private void PrefetchBlobs( - ITracer tracer, - ScalarEnlistment enlistment, - string headCommitId, - List filesList, - List foldersList, - FileBasedDictionary lastPrefetchArgs, - GitObjectsHttpRequestor objectRequestor, - CacheServerInfo cacheServer) - { - BlobPrefetcher blobPrefetcher = new BlobPrefetcher( - tracer, - enlistment, - objectRequestor, - filesList, - foldersList, - lastPrefetchArgs, - ChunkSize, - SearchThreadCount, - DownloadThreadCount, - IndexThreadCount); - - if (blobPrefetcher.FolderList.Count == 0 && - blobPrefetcher.FileList.Count == 0) - { - this.ReportErrorAndExit(tracer, "Did you mean to fetch all blobs? If so, specify `--files '*'` to confirm."); - } - - int matchedBlobCount = 0; - int downloadedBlobCount = 0; - - Func doPrefetch = - () => - { - try - { - blobPrefetcher.PrefetchWithStats( - headCommitId, - isBranch: false, - matchedBlobCount: out matchedBlobCount, - downloadedBlobCount: out downloadedBlobCount); - return !blobPrefetcher.HasFailures; - } - catch (BlobPrefetcher.FetchException e) - { - tracer.RelatedError(e.Message); - return false; - } - }; - - if (this.Verbose) - { - doPrefetch(); - } - else - { - this.ShowStatusWhileRunning(doPrefetch, "Fetching blobs " + this.GetCacheServerDisplay(cacheServer, enlistment.RepoUrl)); - } - - if (blobPrefetcher.HasFailures) - { - Environment.ExitCode = 1; - } - else - { - Console.WriteLine(); - Console.WriteLine("Stats:"); - Console.WriteLine(" Matched blobs: " + matchedBlobCount); - Console.WriteLine(" Already cached: " + (matchedBlobCount - downloadedBlobCount)); - Console.WriteLine(" Downloaded: " + downloadedBlobCount); - } - } - - private bool CheckIsMounted(bool verbose) - { - Func checkMount = () => this.Execute( - this.EnlistmentRootPathParameter, - verb => verb.Output = new StreamWriter(new MemoryStream())) == ReturnCode.Success; - - if (verbose) - { - return ConsoleHelper.ShowStatusWhileRunning( - checkMount, - "Checking that Scalar is mounted", - this.Output, - showSpinner: true, - scalarLogEnlistmentRoot: null); - } - else - { - return checkMount(); - } - } - private string GetCacheServerDisplay(CacheServerInfo cacheServer, string repoUrl) { if (!cacheServer.IsNone(repoUrl)) diff --git a/Scalar/CommandLine/ScalarVerb.cs b/Scalar/CommandLine/ScalarVerb.cs index eb319cd9bb..ed787a5aa6 100644 --- a/Scalar/CommandLine/ScalarVerb.cs +++ b/Scalar/CommandLine/ScalarVerb.cs @@ -169,13 +169,13 @@ public static bool TrySetRequiredGitConfigSettings(Enlistment enlistment) { "core.commitGraph", "true" }, { "core.fscache", "true" }, { "core.gvfs", coreGVFSFlags }, + { ScalarConstants.GitConfig.UseGvfsHelper, "true" }, { "core.multiPackIndex", "true" }, { "core.preloadIndex", "true" }, { "core.safecrlf", "false" }, { "core.untrackedCache", ScalarPlatform.Instance.FileSystem.SupportsUntrackedCache ? "true" : "false" }, { "core.repositoryformatversion", "0" }, { "core.filemode", ScalarPlatform.Instance.FileSystem.SupportsFileMode ? "true" : "false" }, - { GitConfigSetting.CoreVirtualizeObjectsName, "true" }, { "core.bare", "false" }, { "core.logallrefupdates", "true" }, { "core.hookspath", expectedHooksPath }, diff --git a/Scalar/CommandLine/SparseVerb.cs b/Scalar/CommandLine/SparseVerb.cs deleted file mode 100644 index 96fda62c3f..0000000000 --- a/Scalar/CommandLine/SparseVerb.cs +++ /dev/null @@ -1,128 +0,0 @@ -using CommandLine; -using Scalar.Common; -using Scalar.Common.Git; -using Scalar.Common.Http; -using Scalar.Common.Tracing; -using System; -using System.Collections.Generic; -using System.Diagnostics; - -namespace Scalar.CommandLine -{ - [Verb( - SparseVerb.SparseVerbName, - HelpText = @"Add to the list of folders that are included in git's sparse-checkout. -Folders need to be relative to the repo's root directory.") - ] - public class SparseVerb : ScalarVerb.ForExistingEnlistment - { - private const string SparseVerbName = "sparse"; - private const string FolderListSeparator = ";"; - - [Option( - 's', - "set", - Required = false, - Default = "", - HelpText = "A semicolon-delimited list of repo root relative folders to include in the sparse-checkout. Wildcards are not supported.")] - public string FoldersToSet { get; set; } - - [Option( - "set-stdin", - Required = false, - Default = false, - HelpText = "Specify this flag to load folder list from stdin. Folders must be line-delimited and wildcards are not supported.")] - public bool SetFromStdIn { get; set; } - - protected override string VerbName => SparseVerbName; - - protected override void Execute(ScalarEnlistment enlistment) - { - using (JsonTracer tracer = new JsonTracer(ScalarConstants.ScalarEtwProviderName, SparseVerbName)) - { - try - { - CacheServerInfo cacheServer = CacheServerResolver.GetCacheServerFromConfig(enlistment); - - tracer.AddLogFileEventListener( - ScalarEnlistment.GetNewScalarLogFileName(enlistment.ScalarLogsRoot, ScalarConstants.LogFileTypes.Sparse), - EventLevel.Informational, - Keywords.Any); - tracer.WriteStartEvent( - enlistment.EnlistmentRoot, - enlistment.RepoUrl, - cacheServer.Url, - new EventMetadata - { - { "Unattended", this.Unattended }, - { "IsElevated", ScalarPlatform.Instance.IsElevated() }, - { "NamedPipeName", enlistment.NamedPipeName }, - { "ProcessID", Process.GetCurrentProcess().Id }, - { nameof(this.EnlistmentRootPathParameter), this.EnlistmentRootPathParameter }, - { nameof(this.FoldersToSet), this.FoldersToSet }, - { nameof(this.SetFromStdIn), this.SetFromStdIn }, - }); - - if (!this.SetFromStdIn && string.IsNullOrWhiteSpace(this.FoldersToSet)) - { - this.ReportErrorAndExit(tracer, "You must specify folders to set with --set or --set-stdin"); - } - - List foldersToSet = null; - - // Pre-fetch the blobs for the folders that will be added and - // rely on PrefetchVerb for parsing the the list of folders - ReturnCode result = this.Execute( - enlistment, - verb => - { - verb.Commits = false; - verb.ResolvedCacheServer = cacheServer; - verb.SkipVersionCheck = false; - verb.Files = string.Empty; - verb.Folders = this.FoldersToSet; - verb.FoldersFromStdIn = this.SetFromStdIn; - }, - verb => - { - foldersToSet = verb.ParsedFoldersList; - }); - - if (result != ReturnCode.Success) - { - this.ReportErrorAndExit(tracer, "\r\nError during prefetch @ {0}", enlistment.EnlistmentRoot); - } - - this.SparseCheckoutSet(tracer, enlistment, foldersToSet); - } - catch (Exception e) - { - this.ReportErrorAndExit(tracer, "Failed to set folders to sparse-checkout {0}", e.Message); - } - } - } - - private void SparseCheckoutSet(ITracer tracer, ScalarEnlistment enlistment, List foldersToSet) - { - GitProcess git = new GitProcess(enlistment); - GitProcess.Result sparseResult = git.SparseCheckoutSet(foldersToSet); - - if (sparseResult.ExitCodeIsFailure) - { - this.WriteMessage(tracer, $"Failed to set folders to sparse-checkout: {sparseResult.Errors}"); - } - } - - private void WriteMessage(ITracer tracer, string message) - { - this.Output.WriteLine(message); - tracer.RelatedEvent( - EventLevel.Informational, - SparseVerbName, - new EventMetadata - { - { TracingConstants.MessageKey.InfoMessage, message } - }); - } - } -} diff --git a/Scalar/Program.cs b/Scalar/Program.cs index 447ef53608..f199197a91 100644 --- a/Scalar/Program.cs +++ b/Scalar/Program.cs @@ -22,7 +22,6 @@ public static void Main(string[] args) typeof(DehydrateVerb), typeof(DiagnoseVerb), typeof(LogVerb), - typeof(SparseVerb), typeof(MountVerb), typeof(PrefetchVerb), typeof(RepairVerb), diff --git a/Scalar/Scalar.Windows.csproj b/Scalar/Scalar.Windows.csproj index 7b18cc383f..26519605fe 100644 --- a/Scalar/Scalar.Windows.csproj +++ b/Scalar/Scalar.Windows.csproj @@ -116,7 +116,6 @@ - @@ -159,9 +158,6 @@ - - xcopy /Y $(BuildOutputDir)\Scalar.ReadObjectHook.Windows\bin\$(Platform)\$(Configuration)\Scalar.ReadObjectHook.* $(TargetDir) - diff --git a/Scripts/Mac/BuildScalarForMac.sh b/Scripts/Mac/BuildScalarForMac.sh index 1c2b966f9c..3d06e4df9c 100755 --- a/Scripts/Mac/BuildScalarForMac.sh +++ b/Scripts/Mac/BuildScalarForMac.sh @@ -54,9 +54,6 @@ echo 'Restoring packages...' dotnet restore $Scalar_SRCDIR/Scalar.sln /p:Configuration=$CONFIGURATION.Mac --packages $Scalar_PACKAGESDIR /warnasmessage:MSB4011 || exit 1 dotnet build $Scalar_SRCDIR/Scalar.sln --runtime osx-x64 --framework netcoreapp2.1 --configuration $CONFIGURATION.Mac /maxcpucount:1 /warnasmessage:MSB4011 || exit 1 -NATIVEDIR=$Scalar_SRCDIR/Scalar.Native.Mac -xcodebuild -configuration $CONFIGURATION -workspace $NATIVEDIR/Scalar.Native.Mac.xcworkspace build -scheme Scalar.Native.Mac -derivedDataPath $Scalar_OUTPUTDIR/Scalar.Native.Mac || exit 1 - USERNOTIFICATIONDIR=$Scalar_SRCDIR/Scalar.Notifications/Scalar.Mac USERNOTIFICATIONPROJECT="$USERNOTIFICATIONDIR/Scalar.xcodeproj" USERNOTIFICATIONSCHEME="Scalar" @@ -76,10 +73,6 @@ if [ ! -d $Scalar_PUBLISHDIR ]; then mkdir $Scalar_PUBLISHDIR || exit 1 fi -echo 'Copying native binaries to Publish directory...' -cp $Scalar_OUTPUTDIR/Scalar.Native.Mac/Build/Products/$CONFIGURATION/Scalar.ReadObjectHook $Scalar_PUBLISHDIR || exit 1 - -# Publish after native build, so installer package can include the native binaries. dotnet publish $Scalar_SRCDIR/Scalar.sln /p:Configuration=$CONFIGURATION.Mac /p:Platform=x64 --runtime osx-x64 --framework netcoreapp2.1 --self-contained --output $Scalar_PUBLISHDIR /maxcpucount:1 /warnasmessage:MSB4011 || exit 1 echo 'Copying Git installer to the output directory...' diff --git a/Scripts/RunFunctionalTests.bat b/Scripts/RunFunctionalTests.bat index 3369546fcb..8aacc96c40 100644 --- a/Scripts/RunFunctionalTests.bat +++ b/Scripts/RunFunctionalTests.bat @@ -10,14 +10,12 @@ if not "%2"=="--test-scalar-on-path" goto :startFunctionalTests REM Force Scalar.FunctionalTests.exe to use the installed version of Scalar del %Scalar_OUTPUTDIR%\Scalar.FunctionalTests\bin\x64\%Configuration%\netcoreapp2.1\Scalar.exe -del %Scalar_OUTPUTDIR%\Scalar.FunctionalTests\bin\x64\%Configuration%\netcoreapp2.1\Scalar.ReadObjectHook.exe del %Scalar_OUTPUTDIR%\Scalar.FunctionalTests\bin\x64\%Configuration%\netcoreapp2.1\Scalar.Mount.exe del %Scalar_OUTPUTDIR%\Scalar.FunctionalTests\bin\x64\%Configuration%\netcoreapp2.1\Scalar.Service.exe del %Scalar_OUTPUTDIR%\Scalar.FunctionalTests\bin\x64\%Configuration%\netcoreapp2.1\Scalar.Service.UI.exe REM Same for Scalar.FunctionalTests.Windows.exe del %Scalar_OUTPUTDIR%\Scalar.FunctionalTests.Windows\bin\x64\%Configuration%\Scalar.exe -del %Scalar_OUTPUTDIR%\Scalar.FunctionalTests.Windows\bin\x64\%Configuration%\Scalar.ReadObjectHook.exe del %Scalar_OUTPUTDIR%\Scalar.FunctionalTests.Windows\bin\x64\%Configuration%\Scalar.Mount.exe del %Scalar_OUTPUTDIR%\Scalar.FunctionalTests.Windows\bin\x64\%Configuration%\Scalar.Service.exe del %Scalar_OUTPUTDIR%\Scalar.FunctionalTests.Windows\bin\x64\%Configuration%\Scalar.Service.UI.exe