From ec4793df85199e2dbf5f549a81d9ee5778fca5e9 Mon Sep 17 00:00:00 2001 From: Matthew John Cheetham Date: Tue, 26 May 2020 15:38:57 +0100 Subject: [PATCH 1/6] cleanup: delete unused version properties Remove unused Scalar and Git version properties from the ScalarEnlistment type. --- Scalar.Common/ScalarEnlistment.cs | 34 ------------------------------- 1 file changed, 34 deletions(-) diff --git a/Scalar.Common/ScalarEnlistment.cs b/Scalar.Common/ScalarEnlistment.cs index 31b3c9ebd4..247d034629 100644 --- a/Scalar.Common/ScalarEnlistment.cs +++ b/Scalar.Common/ScalarEnlistment.cs @@ -7,9 +7,6 @@ namespace Scalar.Common { public partial class ScalarEnlistment : Enlistment { - private string gitVersion; - private string scalarVersion; - public ScalarEnlistment(string enlistmentRoot, string workingDirectory, string repoUrl, string gitBinPath, GitAuthentication authentication) : base( enlistmentRoot, @@ -33,17 +30,6 @@ public ScalarEnlistment(string enlistmentRoot, string workingDirectory, string r public bool UsesGvfsProtocol { get; protected set; } - // These version properties are only used in logging during clone to track version numbers - public string GitVersion - { - get { return this.gitVersion; } - } - - public string ScalarVersion - { - get { return this.scalarVersion; } - } - public static ScalarEnlistment CreateFromDirectory( string directory, string gitBinRoot, @@ -154,16 +140,6 @@ public static bool TryGetScalarEnlistmentRoot( return false; } - public void SetGitVersion(string gitVersion) - { - this.SetOnce(gitVersion, ref this.gitVersion); - } - - public void SetScalarVersion(string scalarVersion) - { - this.SetOnce(scalarVersion, ref this.scalarVersion); - } - public void InitializeCachePathsFromKey(string localCacheRoot, string localCacheKey) { this.InitializeCachePaths( @@ -202,16 +178,6 @@ public string GetEnlistmentId() return this.GetId(ScalarConstants.GitConfig.EnlistmentId); } - private void SetOnce(T value, ref T valueToSet) - { - if (valueToSet != null) - { - throw new InvalidOperationException("Value already set."); - } - - valueToSet = value; - } - /// /// Creates a hidden directory @ the given path. /// If directory already exists, hides it. From 59afa431911e95e9a64e4b2448f42456b6ecf5a6 Mon Sep 17 00:00:00 2001 From: Matthew John Cheetham Date: Tue, 26 May 2020 15:43:13 +0100 Subject: [PATCH 2/6] cleanup: remove unused file system code Remove various file system and path manipulation code that was no longer used anywhere. Much was cruft carried over from VFS for Git. --- .../FileSystem/IPlatformFileSystem.cs | 1 - .../FileSystem/PhysicalFileSystem.cs | 102 --------- Scalar.Common/NativeMethods.cs | 213 ------------------ Scalar.Common/Platforms/Mac/MacFileSystem.cs | 55 ----- .../Platforms/POSIX/POSIXFileSystem.cs | 2 - .../Platforms/Windows/WindowsFileSystem.cs | 54 ----- Scalar.FunctionalTests/Tools/ScalarHelpers.cs | 210 ----------------- .../Mock/FileSystem/MockFileSystem.cs | 55 +---- .../FileSystem/MockFileSystemWithCallbacks.cs | 10 - .../Mock/FileSystem/MockPlatformFileSystem.cs | 5 - 10 files changed, 1 insertion(+), 706 deletions(-) diff --git a/Scalar.Common/FileSystem/IPlatformFileSystem.cs b/Scalar.Common/FileSystem/IPlatformFileSystem.cs index 91adbf2151..f99f01bb79 100644 --- a/Scalar.Common/FileSystem/IPlatformFileSystem.cs +++ b/Scalar.Common/FileSystem/IPlatformFileSystem.cs @@ -9,7 +9,6 @@ public interface IPlatformFileSystem void FlushFileBuffers(string path); void MoveAndOverwriteFile(string sourceFileName, string destinationFilename); bool TryGetNormalizedPath(string path, out string normalizedPath, out string errorMessage); - void ChangeMode(string path, ushort mode); bool IsExecutable(string filePath); bool IsSocket(string filePath); bool TryCreateDirectoryWithAdminAndUserModifyPermissions(string directoryPath, out string error); diff --git a/Scalar.Common/FileSystem/PhysicalFileSystem.cs b/Scalar.Common/FileSystem/PhysicalFileSystem.cs index b6b23c6786..eac6f67c1d 100644 --- a/Scalar.Common/FileSystem/PhysicalFileSystem.cs +++ b/Scalar.Common/FileSystem/PhysicalFileSystem.cs @@ -2,7 +2,6 @@ using System; using System.Collections.Generic; using System.ComponentModel; -using System.Diagnostics; using System.IO; using System.Security; using System.Threading; @@ -130,11 +129,6 @@ public virtual void MoveAndOverwriteFile(string sourceFileName, string destinati ScalarPlatform.Instance.FileSystem.MoveAndOverwriteFile(sourceFileName, destinationFilename); } - public virtual bool TryGetNormalizedPath(string path, out string normalizedPath, out string errorMessage) - { - return ScalarPlatform.Instance.FileSystem.TryGetNormalizedPath(path, out normalizedPath, out errorMessage); - } - public virtual Stream OpenFileStream(string path, FileMode fileMode, FileAccess fileAccess, FileShare shareMode, FileOptions options, bool callFlushFileBuffers) { if (callFlushFileBuffers) @@ -145,11 +139,6 @@ public virtual Stream OpenFileStream(string path, FileMode fileMode, FileAccess return new FileStream(path, fileMode, fileAccess, shareMode, DefaultStreamBufferSize, options); } - public virtual void FlushFileBuffers(string path) - { - ScalarPlatform.Instance.FileSystem.FlushFileBuffers(path); - } - public virtual void CreateDirectory(string path) { Directory.CreateDirectory(path); @@ -165,11 +154,6 @@ public virtual bool TryCreateOrUpdateDirectoryToAdminModifyPermissions(ITracer t return ScalarPlatform.Instance.FileSystem.TryCreateOrUpdateDirectoryToAdminModifyPermissions(tracer, directoryPath, out error); } - public virtual bool IsSymLink(string path) - { - return (this.GetAttributes(path) & FileAttributes.ReparsePoint) == FileAttributes.ReparsePoint && NativeMethods.IsSymLink(path); - } - public virtual IEnumerable ItemsInDirectory(string path) { DirectoryInfo ntfsDirectory = new DirectoryInfo(path); @@ -201,24 +185,6 @@ public virtual IEnumerable EnumerateFiles(string path, string searchPatt return Directory.EnumerateFiles(path, searchPattern); } - public virtual FileProperties GetFileProperties(string path) - { - FileInfo entry = new FileInfo(path); - if (entry.Exists) - { - return new FileProperties( - entry.Attributes, - entry.CreationTimeUtc, - entry.LastAccessTimeUtc, - entry.LastWriteTimeUtc, - entry.Length); - } - else - { - return FileProperties.DefaultFile; - } - } - public virtual FileAttributes GetAttributes(string path) { return File.GetAttributes(path); @@ -229,31 +195,11 @@ public virtual void SetAttributes(string path, FileAttributes fileAttributes) File.SetAttributes(path, fileAttributes); } - public virtual void MoveFile(string sourcePath, string targetPath) - { - File.Move(sourcePath, targetPath); - } - public virtual string[] GetFiles(string directoryPath, string mask) { return Directory.GetFiles(directoryPath, mask); } - public virtual FileVersionInfo GetVersionInfo(string path) - { - return FileVersionInfo.GetVersionInfo(path); - } - - public virtual bool FileVersionsMatch(FileVersionInfo versionInfo1, FileVersionInfo versionInfo2) - { - return versionInfo1.FileVersion == versionInfo2.FileVersion; - } - - public virtual bool ProductVersionsMatch(FileVersionInfo versionInfo1, FileVersionInfo versionInfo2) - { - return versionInfo1.ProductVersion == versionInfo2.ProductVersion; - } - public bool TryWriteTempFileAndRename(string destinationPath, string contents, out Exception handledException) { handledException = null; @@ -291,54 +237,6 @@ public bool TryWriteTempFileAndRename(string destinationPath, string contents, o } } - public bool TryCopyToTempFileAndRename(string sourcePath, string destinationPath, out Exception handledException) - { - handledException = null; - string tempFilePath = destinationPath + ".temp"; - - try - { - File.Copy(sourcePath, tempFilePath, overwrite: true); - ScalarPlatform.Instance.FileSystem.FlushFileBuffers(tempFilePath); - this.MoveAndOverwriteFile(tempFilePath, destinationPath); - return true; - } - catch (Win32Exception e) - { - handledException = e; - return false; - } - catch (IOException e) - { - handledException = e; - return false; - } - catch (UnauthorizedAccessException e) - { - handledException = e; - return false; - } - } - - public bool TryCreateDirectory(string path, out Exception exception) - { - try - { - Directory.CreateDirectory(path); - } - catch (Exception e) when (e is IOException || - e is UnauthorizedAccessException || - e is ArgumentException || - e is NotSupportedException) - { - exception = e; - return false; - } - - exception = null; - return true; - } - /// /// Recursively deletes a directory and all contained contents. /// diff --git a/Scalar.Common/NativeMethods.cs b/Scalar.Common/NativeMethods.cs index baa90999a4..4f0050e37c 100644 --- a/Scalar.Common/NativeMethods.cs +++ b/Scalar.Common/NativeMethods.cs @@ -2,20 +2,11 @@ using System; using System.IO; using System.Runtime.InteropServices; -using System.Text; namespace Scalar.Common { public static partial class NativeMethods { - private const uint EVENT_TRACE_CONTROL_FLUSH = 3; - - private const uint IO_REPARSE_TAG_MOUNT_POINT = 0xA0000003; - private const uint IO_REPARSE_TAG_SYMLINK = 0xA000000C; - private const uint FSCTL_GET_REPARSE_POINT = 0x000900a8; - - private const int ReparseDataPathBufferLength = 1000; - [Flags] public enum MoveFileFlags : uint { @@ -27,12 +18,6 @@ public enum MoveFileFlags : uint MoveFileFailIfNotTrackable = 0x00000020, // MOVEFILE_FAIL_IF_NOT_TRACKABLE } - [Flags] - public enum FileSystemFlags : uint - { - FILE_RETURNS_CLEANUP_RESULT_INFO = 0x00000200 - } - public static void FlushFileBuffers(string path) { using (SafeFileHandle fileHandle = CreateFile( @@ -56,40 +41,6 @@ public static void FlushFileBuffers(string path) } } - public static bool IsFeatureSupportedByVolume(string volumeRoot, FileSystemFlags flags) - { - uint volumeSerialNumber; - uint maximumComponentLength; - uint fileSystemFlags; - - if (!GetVolumeInformation( - volumeRoot, - null, - 0, - out volumeSerialNumber, - out maximumComponentLength, - out fileSystemFlags, - null, - 0)) - { - ThrowLastWin32Exception($"Failed to get volume information for '{volumeRoot}'"); - } - - return (fileSystemFlags & (uint)flags) == (uint)flags; - } - - public static uint FlushTraceLogger(string sessionName, string sessionGuid, out string logfileName) - { - EventTraceProperties properties = new EventTraceProperties(); - properties.Wnode.BufferSize = (uint)Marshal.SizeOf(properties); - properties.Wnode.Guid = new Guid(sessionGuid); - properties.LoggerNameOffset = (uint)Marshal.OffsetOf(typeof(EventTraceProperties), "LoggerName"); - properties.LogFileNameOffset = (uint)Marshal.OffsetOf(typeof(EventTraceProperties), "LogFileName"); - uint result = ControlTrace(0, sessionName, ref properties, EVENT_TRACE_CONTROL_FLUSH); - logfileName = properties.LogFileName; - return result; - } - public static void MoveFile(string existingFileName, string newFileName, MoveFileFlags flags) { if (!MoveFileEx(existingFileName, newFileName, (uint)flags)) @@ -98,64 +49,6 @@ public static void MoveFile(string existingFileName, string newFileName, MoveFil } } - /// - /// Get the build number of the OS - /// - /// Build number - /// - /// For this method to work correctly, the calling application must have a manifest file - /// that indicates the application supports Windows 10. - /// See https://msdn.microsoft.com/en-us/library/windows/desktop/ms724451(v=vs.85).aspx for details - /// - public static uint GetWindowsBuildNumber() - { - OSVersionInfo versionInfo = new OSVersionInfo(); - versionInfo.OSVersionInfoSize = (uint)Marshal.SizeOf(versionInfo); - if (!GetVersionEx(ref versionInfo)) - { - ThrowLastWin32Exception($"Failed to get OS version info"); - } - - return versionInfo.BuildNumber; - } - - public static bool IsSymLink(string path) - { - using (SafeFileHandle output = CreateFile( - path, - FileAccess.FILE_READ_ATTRIBUTES, - FileShare.Read, - IntPtr.Zero, - FileMode.Open, - FileAttributes.FILE_FLAG_BACKUP_SEMANTICS | FileAttributes.FILE_FLAG_OPEN_REPARSE_POINT, - IntPtr.Zero)) - { - if (output.IsInvalid) - { - ThrowLastWin32Exception($"Invalid handle for '{path}' as symlink"); - } - - REPARSE_DATA_BUFFER reparseData = new REPARSE_DATA_BUFFER(); - reparseData.ReparseDataLength = (4 * sizeof(ushort)) + ReparseDataPathBufferLength; - uint bytesReturned; - if (!DeviceIoControl(output, FSCTL_GET_REPARSE_POINT, IntPtr.Zero, 0, out reparseData, (uint)Marshal.SizeOf(reparseData), out bytesReturned, IntPtr.Zero)) - { - ThrowLastWin32Exception($"Failed to place reparse point for '{path}'"); - } - - return reparseData.ReparseTag == IO_REPARSE_TAG_SYMLINK || reparseData.ReparseTag == IO_REPARSE_TAG_MOUNT_POINT; - } - } - - public static DateTime GetLastRebootTime() - { - // GetTickCount64 is a native call and returns the number - // of milliseconds since the system was started (and not DateTime.Ticks). - // https://msdn.microsoft.com/en-us/library/windows/desktop/ms724411.aspx - TimeSpan uptime = TimeSpan.FromMilliseconds(GetTickCount64()); - return DateTime.Now - uptime; - } - [DllImport("kernel32.dll", SetLastError = true, CharSet = CharSet.Unicode)] private static extern bool MoveFileEx( string existingFileName, @@ -164,111 +57,5 @@ private static extern bool MoveFileEx( [DllImport("kernel32.dll", SetLastError = true)] private static extern bool FlushFileBuffers(SafeFileHandle hFile); - - [DllImport("kernel32.dll", SetLastError = true, CharSet = CharSet.Unicode)] - private static extern bool GetVolumeInformation( - string rootPathName, - StringBuilder volumeNameBuffer, - int volumeNameSize, - out uint volumeSerialNumber, - out uint maximumComponentLength, - out uint fileSystemFlags, - StringBuilder fileSystemNameBuffer, - int nFileSystemNameSize); - - [DllImport("advapi32.dll", EntryPoint = "ControlTraceW", CharSet = CharSet.Unicode)] - private static extern uint ControlTrace( - [In] ulong sessionHandle, - [In] string sessionName, - [In, Out] ref EventTraceProperties properties, - [In] uint controlCode); - - [DllImport("kernel32.dll", CharSet = CharSet.Unicode)] - private static extern bool GetVersionEx([In, Out] ref OSVersionInfo versionInfo); - - // For use with FSCTL_GET_REPARSE_POINT - [DllImport("Kernel32.dll", SetLastError = true, CharSet = CharSet.Unicode)] - private static extern bool DeviceIoControl( - SafeFileHandle hDevice, - uint IoControlCode, - [In] IntPtr InBuffer, - uint nInBufferSize, - [Out] out REPARSE_DATA_BUFFER OutBuffer, - uint nOutBufferSize, - out uint pBytesReturned, - [In] IntPtr Overlapped); - - [DllImport("kernel32.dll")] - private static extern ulong GetTickCount64(); - - [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)] - private struct REPARSE_DATA_BUFFER - { - public uint ReparseTag; - public ushort ReparseDataLength; - public ushort Reserved; - public ushort SubstituteNameOffset; - public ushort SubstituteNameLength; - public ushort PrintNameOffset; - public ushort PrintNameLength; - [MarshalAs(UnmanagedType.ByValArray, SizeConst = ReparseDataPathBufferLength)] - public byte[] PathBuffer; - } - - [StructLayout(LayoutKind.Sequential)] - private struct WNodeHeader - { - public uint BufferSize; - public uint ProviderId; - public ulong HistoricalContext; - public ulong TimeStamp; - public Guid Guid; - public uint ClientContext; - public uint Flags; - } - - [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)] - private struct EventTraceProperties - { - public WNodeHeader Wnode; - public uint BufferSize; - public uint MinimumBuffers; - public uint MaximumBuffers; - public uint MaximumFileSize; - public uint LogFileMode; - public uint FlushTimer; - public uint EnableFlags; - public int AgeLimit; - public uint NumberOfBuffers; - public uint FreeBuffers; - public uint EventsLost; - public uint BuffersWritten; - public uint LogBuffersLost; - public uint RealTimeBuffersLost; - public IntPtr LoggerThreadId; - public uint LogFileNameOffset; - public uint LoggerNameOffset; - - // "You can use the maximum session name (1024 characters) and maximum log file name (1024 characters) lengths to calculate the buffer size and offsets if not known" - // https://msdn.microsoft.com/en-us/library/windows/desktop/aa363696(v=vs.85).aspx - [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 1024)] - public string LoggerName; - - [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 1024)] - public string LogFileName; - } - - [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)] - private struct OSVersionInfo - { - public uint OSVersionInfoSize; - public uint MajorVersion; - public uint MinorVersion; - public uint BuildNumber; - public uint PlatformId; - - [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 128)] - public string CSDVersion; - } } } diff --git a/Scalar.Common/Platforms/Mac/MacFileSystem.cs b/Scalar.Common/Platforms/Mac/MacFileSystem.cs index 15e60446f3..6215ee6bcb 100644 --- a/Scalar.Common/Platforms/Mac/MacFileSystem.cs +++ b/Scalar.Common/Platforms/Mac/MacFileSystem.cs @@ -8,11 +8,6 @@ namespace Scalar.Platform.Mac { public class MacFileSystem : POSIXFileSystem { - public override void ChangeMode(string path, ushort mode) - { - Chmod(path, mode); - } - public override bool IsExecutable(string fileName) { NativeStat.StatBuffer statBuffer = this.StatFile(fileName); @@ -51,9 +46,6 @@ public override bool IsFileSystemSupported(string path, out string error) } } - [DllImport("libc", EntryPoint = "chmod", SetLastError = true)] - private static extern int Chmod(string pathname, ushort mode); - private NativeStat.StatBuffer StatFile(string fileName) { if (NativeStat.Stat(fileName, out NativeStat.StatBuffer statBuffer) != 0) @@ -129,52 +121,5 @@ public struct StatBuffer public long[] QSpare; /* RESERVED: DO NOT USE! */ } } - - private static class NativeFileReader - { - // #define O_RDONLY 0x0000 /* open for reading only */ - private const int ReadOnly = 0x0000; - - internal static bool TryReadFirstByteOfFile(string fileName, byte[] buffer) - { - int fileDescriptor = -1; - bool readStatus = false; - try - { - fileDescriptor = Open(fileName, ReadOnly); - if (fileDescriptor != -1) - { - readStatus = TryReadOneByte(fileDescriptor, buffer); - } - } - finally - { - Close(fileDescriptor); - } - - return readStatus; - } - - [DllImport("libc", EntryPoint = "open", SetLastError = true)] - private static extern int Open(string path, int flag); - - [DllImport("libc", EntryPoint = "close", SetLastError = true)] - private static extern int Close(int fd); - - [DllImport("libc", EntryPoint = "read", SetLastError = true)] - private static extern int Read(int fd, [Out] byte[] buf, int count); - - private static bool TryReadOneByte(int fileDescriptor, byte[] buffer) - { - int numBytes = Read(fileDescriptor, buffer, 1); - - if (numBytes == -1) - { - return false; - } - - return true; - } - } } } diff --git a/Scalar.Common/Platforms/POSIX/POSIXFileSystem.cs b/Scalar.Common/Platforms/POSIX/POSIXFileSystem.cs index a9af8aa9dc..a07ac2db89 100644 --- a/Scalar.Common/Platforms/POSIX/POSIXFileSystem.cs +++ b/Scalar.Common/Platforms/POSIX/POSIXFileSystem.cs @@ -42,8 +42,6 @@ public void MoveAndOverwriteFile(string sourceFileName, string destinationFilena } } - public abstract void ChangeMode(string path, ushort mode); - public bool TryGetNormalizedPath(string path, out string normalizedPath, out string errorMessage) { return POSIXFileSystem.TryGetNormalizedPathImplementation(path, out normalizedPath, out errorMessage); diff --git a/Scalar.Common/Platforms/Windows/WindowsFileSystem.cs b/Scalar.Common/Platforms/Windows/WindowsFileSystem.cs index 36ca3a4e93..36faddebd3 100644 --- a/Scalar.Common/Platforms/Windows/WindowsFileSystem.cs +++ b/Scalar.Common/Platforms/Windows/WindowsFileSystem.cs @@ -1,10 +1,8 @@ -using Microsoft.Win32.SafeHandles; using Scalar.Common; using Scalar.Common.FileSystem; using Scalar.Common.Tracing; using System; using System.IO; -using System.Runtime.InteropServices; using System.Security.AccessControl; using System.Security.Principal; @@ -94,10 +92,6 @@ public void MoveAndOverwriteFile(string sourceFileName, string destinationFilena NativeMethods.MoveFileFlags.MoveFileReplaceExisting); } - public void ChangeMode(string path, ushort mode) - { - } - public bool TryGetNormalizedPath(string path, out string normalizedPath, out string errorMessage) { return WindowsFileSystem.TryGetNormalizedPathImplementation(path, out normalizedPath, out errorMessage); @@ -188,53 +182,5 @@ public bool IsFileSystemSupported(string path, out string error) error = null; return true; } - - private class NativeFileReader - { - private const uint GenericRead = 0x80000000; - private const uint OpenExisting = 3; - - public static bool TryReadFirstByteOfFile(string fileName, byte[] buffer) - { - using (SafeFileHandle handle = Open(fileName)) - { - if (!handle.IsInvalid) - { - return ReadOneByte(handle, buffer); - } - } - - return false; - } - - private static SafeFileHandle Open(string fileName) - { - return CreateFile(fileName, GenericRead, (uint)(FileShare.ReadWrite | FileShare.Delete), 0, OpenExisting, 0, 0); - } - - private static bool ReadOneByte(SafeFileHandle handle, byte[] buffer) - { - int bytesRead = 0; - return ReadFile(handle, buffer, 1, ref bytesRead, 0); - } - - [DllImport("kernel32", SetLastError = true, ThrowOnUnmappableChar = true, CharSet = CharSet.Unicode)] - private static extern SafeFileHandle CreateFile( - string fileName, - uint desiredAccess, - uint shareMode, - uint securityAttributes, - uint creationDisposition, - uint flagsAndAttributes, - int hemplateFile); - - [DllImport("kernel32", SetLastError = true)] - private static extern bool ReadFile( - SafeFileHandle file, - [Out] byte[] buffer, - int numberOfBytesToRead, - ref int numberOfBytesRead, - int overlapped); - } } } diff --git a/Scalar.FunctionalTests/Tools/ScalarHelpers.cs b/Scalar.FunctionalTests/Tools/ScalarHelpers.cs index fa6edd819a..cbf54a5f6d 100644 --- a/Scalar.FunctionalTests/Tools/ScalarHelpers.cs +++ b/Scalar.FunctionalTests/Tools/ScalarHelpers.cs @@ -1,46 +1,11 @@ -using Microsoft.Data.Sqlite; -using Newtonsoft.Json; -using NUnit.Framework; using Scalar.Tests.Should; -using System; -using System.Collections.Generic; -using System.IO; -using System.Text; namespace Scalar.FunctionalTests.Tools { public static class ScalarHelpers { - public const string ModifiedPathsNewLine = "\r\n"; - public const string PlaceholderFieldDelimiter = "\0"; - public const string GitConfigObjectCache = "gvfs.sharedCache"; - public static readonly string BackgroundOpsFile = Path.Combine("databases", "BackgroundGitOperations.dat"); - public static readonly string PlaceholderListFile = Path.Combine("databases", "PlaceholderList.dat"); - public static readonly string RepoMetadataName = Path.Combine("databases", "RepoMetadata.dat"); - - private const string DiskLayoutMajorVersionKey = "DiskLayoutVersion"; - private const string DiskLayoutMinorVersionKey = "DiskLayoutMinorVersion"; - private const string BlobSizesRootKey = "BlobSizesRoot"; - - public static string ConvertPathToGitFormat(string path) - { - return path.Replace(Path.DirectorySeparatorChar, TestConstants.GitPathSeparator); - } - - public static void SaveDiskLayoutVersion(string dotScalarRoot, string majorVersion, string minorVersion) - { - SavePersistedValue(dotScalarRoot, DiskLayoutMajorVersionKey, majorVersion); - SavePersistedValue(dotScalarRoot, DiskLayoutMinorVersionKey, minorVersion); - } - - public static void GetPersistedDiskLayoutVersion(string dotScalarRoot, out string majorVersion, out string minorVersion) - { - majorVersion = GetPersistedValue(dotScalarRoot, DiskLayoutMajorVersionKey); - minorVersion = GetPersistedValue(dotScalarRoot, DiskLayoutMinorVersionKey); - } - public static string GetObjectsRootFromGitConfig(string repoRoot) { ProcessResult result = GitProcess.InvokeProcess(repoRoot, $"config --local {ScalarHelpers.GitConfigObjectCache}"); @@ -49,185 +14,10 @@ public static string GetObjectsRootFromGitConfig(string repoRoot) return result.Output.TrimEnd('\n'); } - public static string GetPersistedBlobSizesRoot(string dotScalarRoot) - { - return GetPersistedValue(dotScalarRoot, BlobSizesRootKey); - } - - public static void SQLiteBlobSizesDatabaseHasEntry(string blobSizesDbPath, string blobSha, long blobSize) - { - RunSqliteCommand(blobSizesDbPath, command => - { - SqliteParameter shaParam = command.CreateParameter(); - shaParam.ParameterName = "@sha"; - command.CommandText = "SELECT size FROM BlobSizes WHERE sha = (@sha)"; - command.Parameters.Add(shaParam); - shaParam.Value = StringToShaBytes(blobSha); - - using (SqliteDataReader reader = command.ExecuteReader()) - { - reader.Read().ShouldBeTrue(); - reader.GetInt64(0).ShouldEqual(blobSize); - } - - return true; - }); - } - - public static string GetAllSQLitePlaceholdersAsString(string placeholdersDbPath) - { - return RunSqliteCommand(placeholdersDbPath, command => - { - command.CommandText = "SELECT path, pathType, sha FROM Placeholder"; - using (SqliteDataReader reader = command.ExecuteReader()) - { - StringBuilder sb = new StringBuilder(); - while (reader.Read()) - { - sb.Append(reader.GetString(0)); - sb.Append(PlaceholderFieldDelimiter); - sb.Append(reader.GetByte(1)); - sb.Append(PlaceholderFieldDelimiter); - if (!reader.IsDBNull(2)) - { - sb.Append(reader.GetString(2)); - sb.Append(PlaceholderFieldDelimiter); - } - - sb.AppendLine(); - } - - return sb.ToString(); - } - }); - } - - public static void AddPlaceholderFolder(string placeholdersDbPath, string path, int pathType) - { - RunSqliteCommand(placeholdersDbPath, command => - { - command.CommandText = "INSERT OR REPLACE INTO Placeholder (path, pathType, sha) VALUES (@path, @pathType, NULL)"; - command.Parameters.AddWithValue("@path", path); - command.Parameters.AddWithValue("@pathType", pathType); - return command.ExecuteNonQuery(); - }); - } - - public static string ReadAllTextFromWriteLockedFile(string filename) - { - // File.ReadAllText and others attempt to open for read and FileShare.None, which always fail on - // the placeholder db and other files that open for write and only share read access - using (StreamReader reader = new StreamReader(File.Open(filename, FileMode.Open, FileAccess.Read, FileShare.ReadWrite))) - { - return reader.ReadToEnd(); - } - } - public static string GetInternalParameter() { return $"\"{{\\\"ServiceName\\\":\\\"{ScalarServiceProcess.TestServiceName}\\\"," + "\\\"StartedByService\\\":false}\""; } - - private static T RunSqliteCommand(string sqliteDbPath, Func runCommand) - { - string connectionString = $"data source={sqliteDbPath}"; - using (SqliteConnection connection = new SqliteConnection(connectionString)) - { - connection.Open(); - using (SqliteCommand command = connection.CreateCommand()) - { - return runCommand(command); - } - } - } - - private static byte[] StringToShaBytes(string sha) - { - byte[] shaBytes = new byte[20]; - - string upperCaseSha = sha.ToUpper(); - int stringIndex = 0; - for (int i = 0; i < 20; ++i) - { - stringIndex = i * 2; - char firstChar = sha[stringIndex]; - char secondChar = sha[stringIndex + 1]; - shaBytes[i] = (byte)(CharToByte(firstChar) << 4 | CharToByte(secondChar)); - } - - return shaBytes; - } - - private static byte CharToByte(char c) - { - if (c >= '0' && c <= '9') - { - return (byte)(c - '0'); - } - - if (c >= 'A' && c <= 'F') - { - return (byte)(10 + (c - 'A')); - } - - Assert.Fail($"Invalid character c: {c}"); - - return 0; - } - - private static string GetPersistedValue(string dotScalarRoot, string key) - { - string metadataPath = Path.Combine(dotScalarRoot, RepoMetadataName); - string json; - using (FileStream fs = new FileStream(metadataPath, FileMode.Open, FileAccess.Read, FileShare.ReadWrite | FileShare.Delete)) - using (StreamReader reader = new StreamReader(fs)) - { - while (!reader.EndOfStream) - { - json = reader.ReadLine(); - json.Substring(0, 2).ShouldEqual("A "); - - KeyValuePair kvp = JsonConvert.DeserializeObject>(json.Substring(2)); - if (kvp.Key == key) - { - return kvp.Value; - } - } - } - - return null; - } - - private static void SavePersistedValue(string dotScalarRoot, string key, string value) - { - string metadataPath = Path.Combine(dotScalarRoot, RepoMetadataName); - - Dictionary repoMetadata = new Dictionary(); - string json; - using (FileStream fs = new FileStream(metadataPath, FileMode.Open, FileAccess.Read, FileShare.ReadWrite | FileShare.Delete)) - using (StreamReader reader = new StreamReader(fs)) - { - while (!reader.EndOfStream) - { - json = reader.ReadLine(); - json.Substring(0, 2).ShouldEqual("A "); - - KeyValuePair kvp = JsonConvert.DeserializeObject>(json.Substring(2)); - repoMetadata.Add(kvp.Key, kvp.Value); - } - } - - repoMetadata[key] = value; - - string newRepoMetadataContents = string.Empty; - - foreach (KeyValuePair kvp in repoMetadata) - { - newRepoMetadataContents += "A " + JsonConvert.SerializeObject(kvp).Trim() + "\r\n"; - } - - File.WriteAllText(metadataPath, newRepoMetadataContents); - } } } diff --git a/Scalar.UnitTests/Mock/FileSystem/MockFileSystem.cs b/Scalar.UnitTests/Mock/FileSystem/MockFileSystem.cs index 51850bb4c0..0364266f16 100644 --- a/Scalar.UnitTests/Mock/FileSystem/MockFileSystem.cs +++ b/Scalar.UnitTests/Mock/FileSystem/MockFileSystem.cs @@ -1,11 +1,10 @@ -using NUnit.Framework; +using NUnit.Framework; using Scalar.Common; using Scalar.Common.FileSystem; using Scalar.Common.Tracing; using Scalar.Tests.Should; using System; using System.Collections.Generic; -using System.Diagnostics; using System.IO; namespace Scalar.UnitTests.Mock.FileSystem @@ -138,13 +137,6 @@ public override void MoveAndOverwriteFile(string sourcePath, string destinationP this.RootDirectory.RemoveFile(sourcePath); } - public override bool TryGetNormalizedPath(string path, out string normalizedPath, out string errorMessage) - { - normalizedPath = path; - errorMessage = null; - return true; - } - public override Stream OpenFileStream(string path, FileMode fileMode, FileAccess fileAccess, FileShare shareMode, FileOptions options, bool flushesToDisk) { MockFile file = this.RootDirectory.FindFile(path); @@ -173,11 +165,6 @@ public override Stream OpenFileStream(string path, FileMode fileMode, FileAccess return file.GetContentStream(); } - public override void FlushFileBuffers(string path) - { - throw new NotImplementedException(); - } - public override void WriteAllText(string path, string contents) { MockFile file = new MockFile(path, contents); @@ -356,19 +343,6 @@ public override IEnumerable EnumerateFiles(string path, string searchPat } } - public override FileProperties GetFileProperties(string path) - { - MockFile file = this.RootDirectory.FindFile(path); - if (file != null) - { - return file.FileProperties; - } - else - { - return FileProperties.DefaultFile; - } - } - public override FileAttributes GetAttributes(string path) { return FileAttributes.Normal; @@ -378,18 +352,6 @@ public override void SetAttributes(string path, FileAttributes fileAttributes) { } - public override void MoveFile(string sourcePath, string targetPath) - { - if (this.AllowMoveFile) - { - return; - } - else - { - throw new NotImplementedException(); - } - } - public override string[] GetFiles(string directoryPath, string mask) { if (!mask.Equals("*")) @@ -409,21 +371,6 @@ public override string[] GetFiles(string directoryPath, string mask) return files.ToArray(); } - public override FileVersionInfo GetVersionInfo(string path) - { - throw new NotImplementedException(); - } - - public override bool FileVersionsMatch(FileVersionInfo versionInfo1, FileVersionInfo versionInfo2) - { - throw new NotImplementedException(); - } - - public override bool ProductVersionsMatch(FileVersionInfo versionInfo1, FileVersionInfo versionInfo2) - { - throw new NotImplementedException(); - } - private Stream CreateAndOpenFileStream(string path) { MockFile file = this.RootDirectory.CreateFile(path); diff --git a/Scalar.UnitTests/Mock/FileSystem/MockFileSystemWithCallbacks.cs b/Scalar.UnitTests/Mock/FileSystem/MockFileSystemWithCallbacks.cs index 8f2fd75087..cce7b2f5d4 100644 --- a/Scalar.UnitTests/Mock/FileSystem/MockFileSystemWithCallbacks.cs +++ b/Scalar.UnitTests/Mock/FileSystem/MockFileSystemWithCallbacks.cs @@ -10,11 +10,6 @@ public class MockFileSystemWithCallbacks : PhysicalFileSystem public Func OnOpenFileStream { get; set; } - public override FileProperties GetFileProperties(string path) - { - throw new InvalidOperationException("GetFileProperties has not been implemented."); - } - public override bool FileExists(string path) { if (this.OnFileExists == null) @@ -66,11 +61,6 @@ public override void SetAttributes(string path, FileAttributes fileAttributes) { } - public override void MoveFile(string sourcePath, string targetPath) - { - throw new NotImplementedException(); - } - public override string[] GetFiles(string directoryPath, string mask) { throw new NotImplementedException(); diff --git a/Scalar.UnitTests/Mock/FileSystem/MockPlatformFileSystem.cs b/Scalar.UnitTests/Mock/FileSystem/MockPlatformFileSystem.cs index 0feb6594fc..f4693d71fb 100644 --- a/Scalar.UnitTests/Mock/FileSystem/MockPlatformFileSystem.cs +++ b/Scalar.UnitTests/Mock/FileSystem/MockPlatformFileSystem.cs @@ -20,11 +20,6 @@ public void MoveAndOverwriteFile(string sourceFileName, string destinationFilena throw new NotSupportedException(); } - public void ChangeMode(string path, ushort mode) - { - throw new NotSupportedException(); - } - public bool TryGetNormalizedPath(string path, out string normalizedPath, out string errorMessage) { errorMessage = null; From 49fa8f03b391ca7243f717b319d563319bd24206 Mon Sep 17 00:00:00 2001 From: Matthew John Cheetham Date: Tue, 14 Jul 2020 15:28:41 +0100 Subject: [PATCH 3/6] cleanup: remove unused enlistment ID methods Remove unsued enlistment ID methods and tests. --- Scalar.Common/ScalarEnlistment.cs | 25 ---------------- .../Common/ScalarEnlistmentTests.cs | 30 ------------------- 2 files changed, 55 deletions(-) diff --git a/Scalar.Common/ScalarEnlistment.cs b/Scalar.Common/ScalarEnlistment.cs index 247d034629..e945cd27cb 100644 --- a/Scalar.Common/ScalarEnlistment.cs +++ b/Scalar.Common/ScalarEnlistment.cs @@ -172,30 +172,5 @@ public bool TryCreateEnlistmentFolders() return true; } - - public string GetEnlistmentId() - { - return this.GetId(ScalarConstants.GitConfig.EnlistmentId); - } - - /// - /// Creates a hidden directory @ the given path. - /// If directory already exists, hides it. - /// - /// Path to desired hidden directory - private void CreateHiddenDirectory(string path) - { - DirectoryInfo dir = Directory.CreateDirectory(path); - dir.Attributes = FileAttributes.Hidden; - } - - private string GetId(string key) - { - GitProcess.ConfigResult configResult = this.CreateGitProcess().GetFromLocalConfig(key); - string value; - string error; - configResult.TryParseAsString(out value, out error, defaultValue: string.Empty); - return value.Trim(); - } } } diff --git a/Scalar.UnitTests/Common/ScalarEnlistmentTests.cs b/Scalar.UnitTests/Common/ScalarEnlistmentTests.cs index ed9a7a5de3..c33185cb11 100644 --- a/Scalar.UnitTests/Common/ScalarEnlistmentTests.cs +++ b/Scalar.UnitTests/Common/ScalarEnlistmentTests.cs @@ -1,8 +1,6 @@ using NUnit.Framework; using Scalar.Common; -using Scalar.Common.Git; using Scalar.Tests.Should; -using Scalar.UnitTests.Mock.Git; using System.Collections.Generic; using System.IO; using System.Runtime.InteropServices; @@ -12,15 +10,6 @@ namespace Scalar.UnitTests.Common [TestFixture] public class ScalarEnlistmentTests { - private const string EnlistmentId = "520dcf634ce34065a06abaa4010a256f"; - - [TestCase] - public void CanGetEnlistmentId() - { - TestScalarEnlistment enlistment = new TestScalarEnlistment(); - enlistment.GetEnlistmentId().ShouldEqual(EnlistmentId); - } - [TestCase] public void TryGetScalarEnlistmentRoot() { @@ -96,24 +85,5 @@ private void TestGetRoot( enlistmentRoot.ShouldEqual(expectedEnlistmentRoot); workingDirectoryRoot.ShouldEqual(expectedWorkingDirectoryRoot); } - - private class TestScalarEnlistment : ScalarEnlistment - { - private MockGitProcess gitProcess; - - public TestScalarEnlistment() - : base("mock:\\path", "mock:\\path", "mock://repoUrl", "mock:\\git", authentication: null) - { - this.gitProcess = new MockGitProcess(); - this.gitProcess.SetExpectedCommandResult( - "config --local scalar.enlistment-id", - () => new GitProcess.Result(EnlistmentId, string.Empty, GitProcess.Result.SuccessCode)); - } - - public override GitProcess CreateGitProcess() - { - return this.gitProcess; - } - } } } From 8984a7fa75da2214c18451a014e0d01d3df3eed9 Mon Sep 17 00:00:00 2001 From: Matthew John Cheetham Date: Tue, 14 Jul 2020 15:44:48 +0100 Subject: [PATCH 4/6] cleanup: remove unused GitProcess methods --- Scalar.Common/Git/GitProcess.cs | 115 +------------------------------- 1 file changed, 3 insertions(+), 112 deletions(-) diff --git a/Scalar.Common/Git/GitProcess.cs b/Scalar.Common/Git/GitProcess.cs index 1cf713b565..b01a3e8b94 100644 --- a/Scalar.Common/Git/GitProcess.cs +++ b/Scalar.Common/Git/GitProcess.cs @@ -102,24 +102,6 @@ public GitProcess(string gitBinPath, string workingDirectoryRoot) public bool LowerPriority { get; set; } - public static Result Clone(string gitBinPath, string url, string targetDir, bool sparse, bool filterBlobs) - { - string sparseArg = sparse ? "--sparse " : string.Empty; - string filterArg = filterBlobs ? "--filter=blob:none" : string.Empty; - - string dir = Paths.ConvertPathToGitFormat(targetDir); - - GitProcess git = new GitProcess(gitBinPath, workingDirectoryRoot: null); - - return git.InvokeGitImpl($"clone {sparseArg} {filterArg} {url} {dir}", - workingDirectory: Directory.GetCurrentDirectory(), - dotGitDirectory: null, - fetchMissingObjects: false, - writeStdIn: null, - parseStdOutLine: null, - timeoutMs: -1); - } - public static Result Init(Enlistment enlistment) { return new GitProcess(enlistment).InvokeGitOutsideEnlistment("init \"" + enlistment.WorkingDirectoryRoot + "\""); @@ -258,7 +240,7 @@ public virtual bool TryStoreCredential(ITracer tracer, string repoUrl, string us /// path=[http.sslCert value] /// username = /// - public virtual bool TryGetCertificatePassword( + public bool TryGetCertificatePassword( ITracer tracer, string certificatePath, out string password, @@ -354,17 +336,6 @@ public virtual bool TryGetCredential( } } - public bool IsValidRepo() - { - Result result = this.InvokeGitAgainstDotGitFolder("rev-parse --show-toplevel"); - return result.ExitCodeIsSuccess; - } - - public Result RevParse(string gitRef) - { - return this.InvokeGitAgainstDotGitFolder("rev-parse " + gitRef); - } - public Result DeleteFromLocalConfig(string settingName) { return this.InvokeGitAgainstDotGitFolder("config --local --unset-all " + settingName); @@ -416,7 +387,7 @@ public Result TryGetAllConfig(bool localOnly, out Dictionary /// The value found for the setting. - public virtual ConfigResult GetFromConfig(string settingName, bool forceOutsideEnlistment = false, PhysicalFileSystem fileSystem = null) + public ConfigResult GetFromConfig(string settingName, bool forceOutsideEnlistment = false, PhysicalFileSystem fileSystem = null) { string command = string.Format("config {0}", settingName); fileSystem = fileSystem ?? new PhysicalFileSystem(); @@ -438,11 +409,6 @@ public ConfigResult GetOriginUrl() return new ConfigResult(this.InvokeGitAgainstDotGitFolder("config --local remote.origin.url"), "remote.origin.url"); } - public Result DiffTree(string sourceTreeish, string targetTreeish, Action onResult) - { - return this.InvokeGitAgainstDotGitFolder("diff-tree -r -t " + sourceTreeish + " " + targetTreeish, null, onResult); - } - public Result CreateBranchWithUpstream(string branchToCreate, string upstreamBranch) { return this.InvokeGitInWorkingDirectoryRoot( @@ -455,11 +421,6 @@ public Result ForceCheckout(string target) return this.InvokeGitInWorkingDirectoryRoot("checkout -f " + target, fetchMissingObjects: true); } - public Result ForceCheckoutAllFiles() - { - return this.InvokeGitInWorkingDirectoryRoot("checkout HEAD -- .", fetchMissingObjects: true); - } - public Result ForegroundFetch(string remote) { // By using "--refmap", we override the configured refspec, @@ -507,21 +468,6 @@ public bool TryGetRemotes(out string[] remotes, out string error) return true; } - public Result SparseCheckoutSet(List foldersToSet) - { - return this.InvokeGitInWorkingDirectoryRoot( - $"sparse-checkout set --stdin", - fetchMissingObjects: true, - writeStdIn: writer => - { - foreach (string path in foldersToSet) - { - string normalizedPath = Paths.ConvertPathToGitFormat(path).Trim(ScalarConstants.GitPathSeparator); - writer.Write(normalizedPath + "\n"); - } - }); - } - public Result GvfsHelperDownloadCommit(string commitId) { return this.InvokeGitInWorkingDirectoryRoot( @@ -539,34 +485,6 @@ public Result GvfsHelperPrefetch() return this.InvokeGitInWorkingDirectoryRoot($"{configString}gvfs-helper prefetch", fetchMissingObjects: false); } - public Result Status(bool allowObjectDownloads, bool useStatusCache, bool showUntracked = false) - { - string command = "status"; - if (!useStatusCache) - { - command += " --no-deserialize"; - } - - if (showUntracked) - { - command += " -uall"; - } - - return this.InvokeGitInWorkingDirectoryRoot(command, fetchMissingObjects: allowObjectDownloads); - } - - public Result UnpackObjects(Stream packFileStream) - { - return this.InvokeGitAgainstDotGitFolder( - "unpack-objects", - stdin => - { - packFileStream.CopyTo(stdin.BaseStream); - stdin.Write('\n'); - }, - null); - } - public Result PackObjects(string filenamePrefix, string gitObjectsDirectory, Action packFileStream) { string packFilePath = Path.Combine(gitObjectsDirectory, ScalarConstants.DotGit.Objects.Pack.Name, filenamePrefix); @@ -627,33 +545,6 @@ public Result RemoteAdd(string remoteName, string url) return this.InvokeGitAgainstDotGitFolder("remote add " + remoteName + " " + url); } - public Result LsTree(string treeish, Action parseStdOutLine, bool recursive, bool showAllTrees = false, bool showDirectories = false) - { - return this.InvokeGitInWorkingDirectoryRoot( - "ls-tree " + (recursive ? "-r " : string.Empty) + (showAllTrees ? "-t " : string.Empty) + (showDirectories ? "-d " : string.Empty) + treeish, - fetchMissingObjects: true, - writeStdIn: null, - parseStdOutLine: parseStdOutLine); - } - - public Result UpdateBranchSymbolicRef(string refToUpdate, string targetRef) - { - return this.InvokeGitAgainstDotGitFolder("symbolic-ref " + refToUpdate + " " + targetRef); - } - - public Result UpdateBranchSha(string refToUpdate, string targetSha) - { - // If oldCommitResult doesn't fail, then the branch exists and update-ref will want the old sha - Result oldCommitResult = this.RevParse(refToUpdate); - string oldSha = string.Empty; - if (oldCommitResult.ExitCodeIsSuccess) - { - oldSha = oldCommitResult.Output.TrimEnd('\n'); - } - - return this.InvokeGitAgainstDotGitFolder("update-ref --no-deref " + refToUpdate + " " + targetSha + " " + oldSha); - } - public Result PrunePacked(string gitObjectDirectory) { return this.InvokeGitAgainstDotGitFolder( @@ -673,7 +564,7 @@ public Result MultiPackIndexRepack(string gitObjectDirectory, string batchSize) return this.InvokeGitAgainstDotGitFolder($"-c pack.threads=1 -c repack.packKeptObjects=true multi-pack-index repack --object-dir=\"{gitObjectDirectory}\" --batch-size={batchSize}"); } - public Process GetGitProcess( + private Process GetGitProcess( string command, string workingDirectory, string dotGitDirectory, From 0a11bf29d858595a67561df02d1e6459191dd175 Mon Sep 17 00:00:00 2001 From: Matthew John Cheetham Date: Tue, 14 Jul 2020 15:45:03 +0100 Subject: [PATCH 5/6] cleanup: remove unused GitVersion checking method --- Scalar/CommandLine/ScalarVerb.cs | 31 ------------------------------- 1 file changed, 31 deletions(-) diff --git a/Scalar/CommandLine/ScalarVerb.cs b/Scalar/CommandLine/ScalarVerb.cs index 6182841d2d..908a9604f3 100644 --- a/Scalar/CommandLine/ScalarVerb.cs +++ b/Scalar/CommandLine/ScalarVerb.cs @@ -489,37 +489,6 @@ private string GetAlternatesPath(ScalarEnlistment enlistment) return Path.Combine(enlistment.WorkingDirectoryRoot, ScalarConstants.DotGit.Objects.Info.Alternates); } - private void CheckGitVersion(ITracer tracer, ScalarEnlistment enlistment, out string version) - { - GitVersion gitVersion = null; - if (string.IsNullOrEmpty(enlistment.GitBinPath)) - { - this.ReportErrorAndExit(tracer, "Unable to find Git version on PATH"); - } - - if (!GitProcess.TryGetVersion(enlistment.GitBinPath, out gitVersion, out string error)) - { - this.ReportErrorAndExit(tracer, $"Unable to parse Git version at '{enlistment.GitBinPath}':\n{error}"); - } - - version = gitVersion.ToString(); - - if (gitVersion.Platform != ScalarConstants.SupportedGitVersion.Platform) - { - this.ReportErrorAndExit(tracer, "Error: Invalid version of git {0} at {1}. Must use scalar version.", version, enlistment.GitBinPath); - } - - if (gitVersion.IsLessThan(ScalarConstants.SupportedGitVersion)) - { - this.ReportErrorAndExit( - tracer, - "Error: Installed git version {0} at {1} is less than the supported version of {2}.", - gitVersion, - enlistment.GitBinPath, - ScalarConstants.SupportedGitVersion); - } - } - public abstract class ForExistingEnlistment : ScalarVerb { public ForExistingEnlistment(bool validateOrigin = true) : base(validateOrigin) From 47ed0fe55a8ae826ae97b1bcd40e400b4eecb16c Mon Sep 17 00:00:00 2001 From: Matthew John Cheetham Date: Wed, 15 Jul 2020 10:30:38 +0100 Subject: [PATCH 6/6] cleanup: delete several unused types Delete several unused types (and their tests). Many of these types were only referenced by themselves, or their own unit tests! These are a hold-over from the forking from VFS for Git. --- Scalar.Common/ConcurrentHashSet.cs | 57 --- Scalar.Common/Git/DiffTreeResult.cs | 220 ----------- Scalar.Common/Git/GitOid.cs | 17 - Scalar.Common/Git/GitPathConverter.cs | 58 --- Scalar.Common/Git/RefLogEntry.cs | 44 --- Scalar.Common/Git/Sha1Id.cs | 206 ---------- Scalar.Common/IHeartBeatMetadataProvider.cs | 9 - .../BatchedLooseObjectDeserializer.cs | 132 ------- .../NetworkStreams/RestrictedStream.cs | 154 -------- Scalar.Common/StreamUtil.cs | 91 ----- .../Common/DiffTreeResultTests.cs | 371 ------------------ Scalar.UnitTests/Common/Git/Sha1IdTests.cs | 47 --- .../Common/GitPathConverterTests.cs | 56 --- Scalar.UnitTests/Common/RefLogEntryTests.cs | 63 --- 14 files changed, 1525 deletions(-) delete mode 100644 Scalar.Common/ConcurrentHashSet.cs delete mode 100644 Scalar.Common/Git/DiffTreeResult.cs delete mode 100644 Scalar.Common/Git/GitOid.cs delete mode 100644 Scalar.Common/Git/GitPathConverter.cs delete mode 100644 Scalar.Common/Git/RefLogEntry.cs delete mode 100644 Scalar.Common/Git/Sha1Id.cs delete mode 100644 Scalar.Common/IHeartBeatMetadataProvider.cs delete mode 100644 Scalar.Common/NetworkStreams/BatchedLooseObjectDeserializer.cs delete mode 100644 Scalar.Common/NetworkStreams/RestrictedStream.cs delete mode 100644 Scalar.Common/StreamUtil.cs delete mode 100644 Scalar.UnitTests/Common/DiffTreeResultTests.cs delete mode 100644 Scalar.UnitTests/Common/Git/Sha1IdTests.cs delete mode 100644 Scalar.UnitTests/Common/GitPathConverterTests.cs delete mode 100644 Scalar.UnitTests/Common/RefLogEntryTests.cs diff --git a/Scalar.Common/ConcurrentHashSet.cs b/Scalar.Common/ConcurrentHashSet.cs deleted file mode 100644 index e886bcb6d3..0000000000 --- a/Scalar.Common/ConcurrentHashSet.cs +++ /dev/null @@ -1,57 +0,0 @@ -using System.Collections; -using System.Collections.Concurrent; -using System.Collections.Generic; - -namespace Scalar.Common -{ - public class ConcurrentHashSet : IEnumerable - { - private ConcurrentDictionary dictionary; - - public ConcurrentHashSet() - { - this.dictionary = new ConcurrentDictionary(); - } - - public ConcurrentHashSet(IEqualityComparer comparer) - { - this.dictionary = new ConcurrentDictionary(comparer); - } - - public int Count - { - get { return this.dictionary.Count; } - } - - public bool Add(T entry) - { - return this.dictionary.TryAdd(entry, true); - } - - public bool Contains(T item) - { - return this.dictionary.ContainsKey(item); - } - - public void Clear() - { - this.dictionary.Clear(); - } - - public IEnumerator GetEnumerator() - { - return this.dictionary.Keys.GetEnumerator(); - } - - IEnumerator IEnumerable.GetEnumerator() - { - return this.GetEnumerator(); - } - - public bool TryRemove(T key) - { - bool value; - return this.dictionary.TryRemove(key, out value); - } - } -} diff --git a/Scalar.Common/Git/DiffTreeResult.cs b/Scalar.Common/Git/DiffTreeResult.cs deleted file mode 100644 index 8ec70fab91..0000000000 --- a/Scalar.Common/Git/DiffTreeResult.cs +++ /dev/null @@ -1,220 +0,0 @@ -using System; -using System.Collections.Generic; -using System.IO; -using System.Linq; - -namespace Scalar.Common.Git -{ - public class DiffTreeResult - { - public const string TreeMarker = "tree "; - public const string BlobMarker = "blob "; - - public const int TypeMarkerStartIndex = 7; - - private const ushort SymLinkFileIndexEntry = 0xA000; - - private static readonly HashSet ValidTreeModes = new HashSet() { "040000" }; - - public enum Operations - { - Unknown, - CopyEdit, - RenameEdit, - Modify, - Delete, - Add, - Unmerged, - TypeChange, - } - - public Operations Operation { get; set; } - public bool SourceIsDirectory { get; set; } - public bool TargetIsDirectory { get; set; } - public bool TargetIsSymLink { get; set; } - public string TargetPath { get; set; } - public string SourceSha { get; set; } - public string TargetSha { get; set; } - public ushort SourceMode { get; set; } - public ushort TargetMode { get; set; } - - public static DiffTreeResult ParseFromDiffTreeLine(string line) - { - if (string.IsNullOrEmpty(line)) - { - throw new ArgumentException("Line to parse cannot be null or empty", nameof(line)); - } - - /* - * The lines passed to this method should be the result of a call to git diff-tree -r -t (sourceTreeish) (targetTreeish) - * - * Example output lines from git diff-tree - * :000000 040000 0000000000000000000000000000000000000000 cee82f9d431bf610404f67bcdda3fee76f0c1dd5 A\tScalar/FastFetch/Git - * :000000 100644 0000000000000000000000000000000000000000 cdc036f9d561f14d908e0a0c337105b53c778e5e A\tScalar/FastFetch/Git/FastFetchGitObjects.cs - * :040000 000000 f68b90da732791438d67c0326997a2d26e4c2de4 0000000000000000000000000000000000000000 D\tScalar/Scalar.CLI - * :100644 000000 1242fc97c612ff286a5f1221d569508600ca5e06 0000000000000000000000000000000000000000 D\tScalar/Scalar.CLI/Scalar.CLI.csproj - * :040000 040000 3823348f91113a619eed8f48fe597cc9c7d088d8 fd56ff77b12a0b76567cb55ed4950272eac8b8f6 M\tScalar/Scalar.Common - * :100644 100644 57d9c737c8a48632cfbb12cae00c97d512b9f155 524d7dbcebd33e4007c52711d3f21b17373de454 M\tScalar/Scalar.Common/Scalar.Common.csproj - * ^-[0] ^-[1] ^-[2] ^-[3] ^-[4] - * ^-tab - * ^-[5] - * - * This output will only happen if -C or -M is passed to the diff-tree command - * Since we are not passing those options we shouldn't have to handle this format. - * :100644 100644 3ac7d60a25bb772af1d5843c76e8a070c062dc5d c31a95125b8a6efd401488839a7ed1288ce01634 R094\tScalar/Scalar.CLI/CommandLine/CloneVerb.cs\tScalar/Scalar/CommandLine/CloneVerb.cs - */ - - if (!line.StartsWith(":")) - { - throw new ArgumentException($"diff-tree lines should start with a :", nameof(line)); - } - - // Skip the colon at the front - line = line.Substring(1); - - // Filenames may contain spaces, but always follow a \t. Other fields are space delimited. - // Splitting on \t will give us the mode, sha, operation in parts[0] and that path in parts[1] and optionally in paths[2] - string[] parts = line.Split(new[] { '\t' }, count: 2); - - // Take the mode, sha, operation part and split on a space then add the paths that were split on a tab to the end - parts = parts[0].Split(' ').Concat(parts.Skip(1)).ToArray(); - - if (parts.Length != 6 || - parts[5].Contains('\t')) - { - // Look at file history to see how -C -M with 7 parts could be handled - throw new ArgumentException($"diff-tree lines should have 6 parts unless passed -C or -M which this method doesn't handle", nameof(line)); - } - - DiffTreeResult result = new DiffTreeResult(); - result.SourceIsDirectory = ValidTreeModes.Contains(parts[0]); - result.TargetIsDirectory = ValidTreeModes.Contains(parts[1]); - result.SourceMode = Convert.ToUInt16(parts[0], 8); - result.TargetMode = Convert.ToUInt16(parts[1], 8); - - if (!result.TargetIsDirectory) - { - result.TargetIsSymLink = result.TargetMode == SymLinkFileIndexEntry; - } - - result.SourceSha = parts[2]; - result.TargetSha = parts[3]; - result.Operation = DiffTreeResult.ParseOperation(parts[4]); - result.TargetPath = ConvertPathToUtf8Path(parts[5]); - if (result.TargetIsDirectory || result.SourceIsDirectory) - { - // Since diff-tree is not doing rename detection, file->directory or directory->file transformations are always multiple lines - // with a delete line and an add line - // :000000 040000 0000000000000000000000000000000000000000 cee82f9d431bf610404f67bcdda3fee76f0c1dd5 A\tScalar/FastFetch/Git - // :040000 040000 3823348f91113a619eed8f48fe597cc9c7d088d8 fd56ff77b12a0b76567cb55ed4950272eac8b8f6 M\tScalar/Scalar.Common - // :040000 000000 f68b90da732791438d67c0326997a2d26e4c2de4 0000000000000000000000000000000000000000 D\tScalar/Scalar.CLI - result.TargetPath = AppendPathSeparatorIfNeeded(result.TargetPath); - } - - return result; - } - - /// - /// Parse the output of calling git ls-tree - /// - /// A line that was output from calling git ls-tree - /// A DiffTreeResult build from the output line - /// - /// The call to ls-tree could be any of the following - /// git ls-tree (treeish) - /// git ls-tree -r (treeish) - /// git ls-tree -t (treeish) - /// git ls-tree -r -t (treeish) - /// - public static DiffTreeResult ParseFromLsTreeLine(string line) - { - if (string.IsNullOrEmpty(line)) - { - throw new ArgumentException("Line to parse cannot be null or empty", nameof(line)); - } - - /* - * Example output lines from ls-tree - * - * 040000 tree 73b881d52b607b0f3e9e620d36f556d3d233a11d\tScalar - * 100644 blob 44c5f5cba4b29d31c2ad06eed51ea02af76c27c0\tReadme.md - * 100755 blob 196142fbb753c0a3c7c6690323db7aa0a11f41ec\tScripts/BuildScalarForMac.sh - * ^-mode ^-marker ^-tab - * ^-sha ^-path - */ - - // Everything from ls-tree is an add. - if (IsLsTreeLineOfType(line, TreeMarker)) - { - DiffTreeResult treeAdd = new DiffTreeResult(); - treeAdd.TargetIsDirectory = true; - treeAdd.TargetPath = AppendPathSeparatorIfNeeded(ConvertPathToUtf8Path(line.Substring(line.LastIndexOf("\t") + 1))); - treeAdd.Operation = DiffTreeResult.Operations.Add; - - return treeAdd; - } - else - { - if (IsLsTreeLineOfType(line, BlobMarker)) - { - DiffTreeResult blobAdd = new DiffTreeResult(); - blobAdd.TargetMode = Convert.ToUInt16(line.Substring(0, 6), 8); - blobAdd.TargetIsSymLink = blobAdd.TargetMode == SymLinkFileIndexEntry; - blobAdd.TargetSha = line.Substring(TypeMarkerStartIndex + BlobMarker.Length, ScalarConstants.ShaStringLength); - blobAdd.TargetPath = ConvertPathToUtf8Path(line.Substring(line.LastIndexOf("\t") + 1)); - blobAdd.Operation = DiffTreeResult.Operations.Add; - - return blobAdd; - } - else - { - return null; - } - } - } - - public static bool IsLsTreeLineOfType(string line, string typeMarker) - { - if (line.Length <= TypeMarkerStartIndex + typeMarker.Length) - { - return false; - } - - return line.IndexOf(typeMarker, TypeMarkerStartIndex, typeMarker.Length, StringComparison.OrdinalIgnoreCase) == TypeMarkerStartIndex; - } - - private static string AppendPathSeparatorIfNeeded(string path) - { - return path.Last() == Path.DirectorySeparatorChar ? path : path + Path.DirectorySeparatorChar; - } - - private static Operations ParseOperation(string gitOperationString) - { - switch (gitOperationString) - { - case "U": return Operations.Unmerged; - case "M": return Operations.Modify; - case "A": return Operations.Add; - case "D": return Operations.Delete; - case "X": return Operations.Unknown; - case "T": return Operations.TypeChange; - default: - if (gitOperationString.StartsWith("C")) - { - return Operations.CopyEdit; - } - else if (gitOperationString.StartsWith("R")) - { - return Operations.RenameEdit; - } - - throw new InvalidDataException("Unrecognized diff-tree operation: " + gitOperationString); - } - } - - private static string ConvertPathToUtf8Path(string relativePath) - { - return GitPathConverter.ConvertPathOctetsToUtf8(relativePath.Trim('"')).Replace(ScalarConstants.GitPathSeparator, Path.DirectorySeparatorChar); - } - } -} diff --git a/Scalar.Common/Git/GitOid.cs b/Scalar.Common/Git/GitOid.cs deleted file mode 100644 index c47b612ba5..0000000000 --- a/Scalar.Common/Git/GitOid.cs +++ /dev/null @@ -1,17 +0,0 @@ -using System.Runtime.InteropServices; - -namespace Scalar.Common.Git -{ - [StructLayout(LayoutKind.Sequential)] - public struct GitOid - { - // OIDs are 20 bytes long - [MarshalAs(UnmanagedType.ByValArray, SizeConst = 20)] - public byte[] Id; - - public override string ToString() - { - return SHA1Util.HexStringFromBytes(this.Id); - } - } -} diff --git a/Scalar.Common/Git/GitPathConverter.cs b/Scalar.Common/Git/GitPathConverter.cs deleted file mode 100644 index 93f7cfeddd..0000000000 --- a/Scalar.Common/Git/GitPathConverter.cs +++ /dev/null @@ -1,58 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Text; - -namespace Scalar.Common.Git -{ - public static class GitPathConverter - { - private const int CharsInOctet = 3; - private const char OctetIndicator = '\\'; - - public static string ConvertPathOctetsToUtf8(string filePath) - { - if (filePath == null) - { - return null; - } - - int octetIndicatorIndex = filePath.IndexOf(OctetIndicator); - if (octetIndicatorIndex == -1) - { - return filePath; - } - - StringBuilder converted = new StringBuilder(); - List octets = new List(); - int index = 0; - while (octetIndicatorIndex != -1) - { - converted.Append(filePath.Substring(index, octetIndicatorIndex - index)); - while (octetIndicatorIndex < filePath.Length && filePath[octetIndicatorIndex] == OctetIndicator) - { - string octet = filePath.Substring(octetIndicatorIndex + 1, CharsInOctet); - octets.Add(Convert.ToByte(octet, 8)); - octetIndicatorIndex += CharsInOctet + 1; - } - - AddOctetsAsUtf8(converted, octets); - index = octetIndicatorIndex; - octetIndicatorIndex = filePath.IndexOf(OctetIndicator, octetIndicatorIndex); - } - - AddOctetsAsUtf8(converted, octets); - converted.Append(filePath.Substring(index)); - - return converted.ToString(); - } - - private static void AddOctetsAsUtf8(StringBuilder converted, List octets) - { - if (octets.Count > 0) - { - converted.Append(Encoding.UTF8.GetChars(octets.ToArray())); - octets.Clear(); - } - } - } -} diff --git a/Scalar.Common/Git/RefLogEntry.cs b/Scalar.Common/Git/RefLogEntry.cs deleted file mode 100644 index d8634b1ae6..0000000000 --- a/Scalar.Common/Git/RefLogEntry.cs +++ /dev/null @@ -1,44 +0,0 @@ -namespace Scalar.Common.Git -{ - public class RefLogEntry - { - public RefLogEntry(string sourceSha, string targetSha, string reason) - { - this.SourceSha = sourceSha; - this.TargetSha = targetSha; - this.Reason = reason; - } - - public string SourceSha { get; } - public string TargetSha { get; } - public string Reason { get; } - - public static bool TryParse(string line, out RefLogEntry entry) - { - entry = null; - if (string.IsNullOrEmpty(line)) - { - return false; - } - - if (line.Length < ScalarConstants.ShaStringLength + 1 + ScalarConstants.ShaStringLength) - { - return false; - } - - string sourceSha = line.Substring(0, ScalarConstants.ShaStringLength); - string targetSha = line.Substring(ScalarConstants.ShaStringLength + 1, ScalarConstants.ShaStringLength); - - int reasonStart = line.LastIndexOf("\t"); - if (reasonStart < 0) - { - return false; - } - - string reason = line.Substring(reasonStart + 1); - - entry = new RefLogEntry(sourceSha, targetSha, reason); - return true; - } - } -} diff --git a/Scalar.Common/Git/Sha1Id.cs b/Scalar.Common/Git/Sha1Id.cs deleted file mode 100644 index 3ccdadce24..0000000000 --- a/Scalar.Common/Git/Sha1Id.cs +++ /dev/null @@ -1,206 +0,0 @@ -using System; -using System.Runtime.InteropServices; - -namespace Scalar.Common.Git -{ - [StructLayout(LayoutKind.Explicit, Size = ShaBufferLength, Pack = 1)] - public struct Sha1Id - { - public static readonly Sha1Id None = new Sha1Id(); - - private const int ShaBufferLength = (2 * sizeof(ulong)) + sizeof(uint); - private const int ShaStringLength = 2 * ShaBufferLength; - - [FieldOffset(0)] - private ulong shaBytes1Through8; - - [FieldOffset(8)] - private ulong shaBytes9Through16; - - [FieldOffset(16)] - private uint shaBytes17Through20; - - public Sha1Id(ulong shaBytes1Through8, ulong shaBytes9Through16, uint shaBytes17Through20) - { - this.shaBytes1Through8 = shaBytes1Through8; - this.shaBytes9Through16 = shaBytes9Through16; - this.shaBytes17Through20 = shaBytes17Through20; - } - - public Sha1Id(string sha) - { - if (sha == null) - { - throw new ArgumentNullException(nameof(sha)); - } - - if (sha.Length != ShaStringLength) - { - throw new ArgumentException($"Must be length {ShaStringLength}", nameof(sha)); - } - - this.shaBytes1Through8 = ShaSubStringToULong(sha.Substring(0, 16)); - this.shaBytes9Through16 = ShaSubStringToULong(sha.Substring(16, 16)); - this.shaBytes17Through20 = ShaSubStringToUInt(sha.Substring(32, 8)); - } - - public static bool TryParse(string sha, out Sha1Id sha1, out string error) - { - error = null; - - try - { - sha1 = new Sha1Id(sha); - return true; - } - catch (Exception e) - { - error = e.Message; - } - - sha1 = new Sha1Id(0, 0, 0); - return false; - } - - public static void ShaBufferToParts( - byte[] shaBuffer, - out ulong shaBytes1Through8, - out ulong shaBytes9Through16, - out uint shaBytes17Through20) - { - if (shaBuffer == null) - { - throw new ArgumentNullException(nameof(shaBuffer)); - } - - if (shaBuffer.Length != ShaBufferLength) - { - throw new ArgumentException($"Must be length {ShaBufferLength}", nameof(shaBuffer)); - } - - unsafe - { - fixed (byte* firstChunk = &shaBuffer[0], secondChunk = &shaBuffer[sizeof(ulong)], thirdChunk = &shaBuffer[sizeof(ulong) * 2]) - { - shaBytes1Through8 = *(ulong*)firstChunk; - shaBytes9Through16 = *(ulong*)secondChunk; - shaBytes17Through20 = *(uint*)thirdChunk; - } - } - } - - public void ToBuffer(byte[] shaBuffer) - { - unsafe - { - fixed (byte* firstChunk = &shaBuffer[0], secondChunk = &shaBuffer[sizeof(ulong)], thirdChunk = &shaBuffer[sizeof(ulong) * 2]) - { - *(ulong*)firstChunk = this.shaBytes1Through8; - *(ulong*)secondChunk = this.shaBytes9Through16; - *(uint*)thirdChunk = this.shaBytes17Through20; - } - } - } - - public override string ToString() - { - char[] shaString = new char[ShaStringLength]; - BytesToCharArray(shaString, 0, this.shaBytes1Through8, sizeof(ulong)); - BytesToCharArray(shaString, 2 * sizeof(ulong), this.shaBytes9Through16, sizeof(ulong)); - BytesToCharArray(shaString, 2 * (2 * sizeof(ulong)), this.shaBytes17Through20, sizeof(uint)); - return new string(shaString, 0, shaString.Length); - } - - private static void BytesToCharArray(char[] shaString, int startIndex, ulong shaBytes, int numBytes) - { - byte b; - int firstArrayIndex; - for (int i = 0; i < numBytes; ++i) - { - b = (byte)(shaBytes >> (i * 8)); - firstArrayIndex = startIndex + (i * 2); - shaString[firstArrayIndex] = GetHexValue(b / 16); - shaString[firstArrayIndex + 1] = GetHexValue(b % 16); - } - } - - private static ulong ShaSubStringToULong(string shaSubString) - { - if (shaSubString == null) - { - throw new ArgumentNullException(nameof(shaSubString)); - } - - if (shaSubString.Length != sizeof(ulong) * 2) - { - throw new ArgumentException($"Must be length {sizeof(ulong) * 2}", nameof(shaSubString)); - } - - ulong bytes = 0; - string upperCaseSha = shaSubString.ToUpper(); - int stringIndex = 0; - for (int i = 0; i < sizeof(ulong); ++i) - { - stringIndex = i * 2; - char firstChar = shaSubString[stringIndex]; - char secondChar = shaSubString[stringIndex + 1]; - byte nextByte = (byte)(CharToByte(firstChar) << 4 | CharToByte(secondChar)); - bytes = bytes | ((ulong)nextByte << (i * 8)); - } - - return bytes; - } - - private static uint ShaSubStringToUInt(string shaSubString) - { - if (shaSubString == null) - { - throw new ArgumentNullException(nameof(shaSubString)); - } - - if (shaSubString.Length != sizeof(uint) * 2) - { - throw new ArgumentException($"Must be length {sizeof(uint) * 2}", nameof(shaSubString)); - } - - uint bytes = 0; - string upperCaseSha = shaSubString.ToUpper(); - int stringIndex = 0; - for (int i = 0; i < sizeof(uint); ++i) - { - stringIndex = i * 2; - char firstChar = shaSubString[stringIndex]; - char secondChar = shaSubString[stringIndex + 1]; - byte nextByte = (byte)(CharToByte(firstChar) << 4 | CharToByte(secondChar)); - bytes = bytes | ((uint)nextByte << (i * 8)); - } - - return bytes; - } - - private static char GetHexValue(int i) - { - if (i < 10) - { - return (char)(i + '0'); - } - - return (char)(i - 10 + 'A'); - } - - private static byte CharToByte(char c) - { - if (c >= '0' && c <= '9') - { - return (byte)(c - '0'); - } - - if (c >= 'A' && c <= 'F') - { - return (byte)(10 + (c - 'A')); - } - - throw new ArgumentException($"Invalid character {c}", nameof(c)); - } - } -} diff --git a/Scalar.Common/IHeartBeatMetadataProvider.cs b/Scalar.Common/IHeartBeatMetadataProvider.cs deleted file mode 100644 index 7389fa3716..0000000000 --- a/Scalar.Common/IHeartBeatMetadataProvider.cs +++ /dev/null @@ -1,9 +0,0 @@ -using Scalar.Common.Tracing; - -namespace Scalar.Common -{ - public interface IHeartBeatMetadataProvider - { - EventMetadata GetAndResetHeartBeatMetadata(out bool logToFile); - } -} diff --git a/Scalar.Common/NetworkStreams/BatchedLooseObjectDeserializer.cs b/Scalar.Common/NetworkStreams/BatchedLooseObjectDeserializer.cs deleted file mode 100644 index 006b346977..0000000000 --- a/Scalar.Common/NetworkStreams/BatchedLooseObjectDeserializer.cs +++ /dev/null @@ -1,132 +0,0 @@ -using System; -using System.IO; -using System.Linq; -using System.Text; - -namespace Scalar.Common.NetworkStreams -{ - /// - /// Deserializer for concatenated loose objects. - /// - public class BatchedLooseObjectDeserializer - { - private const int NumObjectIdBytes = 20; - private const int NumObjectHeaderBytes = NumObjectIdBytes + sizeof(long); - private static readonly byte[] ExpectedHeader - = new byte[] - { - (byte)'G', (byte)'V', (byte)'F', (byte)'S', (byte)' ', // Magic - 1 // Version - }; - - private readonly Stream source; - private readonly OnLooseObject onLooseObject; - - public BatchedLooseObjectDeserializer(Stream source, OnLooseObject onLooseObject) - { - this.source = source; - this.onLooseObject = onLooseObject; - } - - /// - /// Invoked when the full content of a single loose object is available. - /// - public delegate void OnLooseObject(Stream objectStream, string sha1); - - /// - /// Read all the objects from the source stream and call for each. - /// - /// The total number of objects read - public int ProcessObjects() - { - this.ValidateHeader(); - - // Start reading objects - int numObjectsRead = 0; - byte[] curObjectHeader = new byte[NumObjectHeaderBytes]; - - while (true) - { - bool keepReading = this.ShouldContinueReading(curObjectHeader); - if (!keepReading) - { - break; - } - - // Get the length - long curLength = BitConverter.ToInt64(curObjectHeader, NumObjectIdBytes); - - // Handle the loose object - using (Stream rawObjectData = new RestrictedStream(this.source, curLength)) - { - string objectId = SHA1Util.HexStringFromBytes(curObjectHeader, NumObjectIdBytes); - - if (objectId.Equals(ScalarConstants.AllZeroSha)) - { - throw new RetryableException("Received all-zero SHA before end of stream"); - } - - this.onLooseObject(rawObjectData, objectId); - numObjectsRead++; - } - } - - return numObjectsRead; - } - - /// - /// Parse the current object header to check if we've reached the end. - /// - /// true if the end of the stream has been reached, false if not - private bool ShouldContinueReading(byte[] curObjectHeader) - { - int totalBytes = StreamUtil.TryReadGreedy( - this.source, - curObjectHeader, - 0, - curObjectHeader.Length); - - if (totalBytes == NumObjectHeaderBytes) - { - // Successful header read - return true; - } - else if (totalBytes == NumObjectIdBytes) - { - // We may have finished reading all the objects - for (int i = 0; i < NumObjectIdBytes; i++) - { - if (curObjectHeader[i] != 0) - { - throw new RetryableException( - string.Format( - "Reached end of stream before we got the expected zero-object ID Buffer: {0}", - SHA1Util.HexStringFromBytes(curObjectHeader))); - } - } - - return false; - } - else - { - throw new RetryableException( - string.Format( - "Reached end of stream before expected {0} or {1} bytes. Got {2}. Buffer: {3}", - NumObjectHeaderBytes, - NumObjectIdBytes, - totalBytes, - SHA1Util.HexStringFromBytes(curObjectHeader))); - } - } - - private void ValidateHeader() - { - byte[] headerBuf = new byte[ExpectedHeader.Length]; - StreamUtil.TryReadGreedy(this.source, headerBuf, 0, headerBuf.Length); - if (!headerBuf.SequenceEqual(ExpectedHeader)) - { - throw new InvalidDataException("Unexpected header: " + Encoding.UTF8.GetString(headerBuf)); - } - } - } -} diff --git a/Scalar.Common/NetworkStreams/RestrictedStream.cs b/Scalar.Common/NetworkStreams/RestrictedStream.cs deleted file mode 100644 index bd9059297c..0000000000 --- a/Scalar.Common/NetworkStreams/RestrictedStream.cs +++ /dev/null @@ -1,154 +0,0 @@ -using System; -using System.IO; - -namespace Scalar.Common.NetworkStreams -{ - /// - /// Stream wrapper for a length-limited subview of another stream. - /// - internal class RestrictedStream : Stream - { - private readonly Stream stream; - private readonly long length; - private readonly bool leaveOpen; - - private long position; - private bool closed; - - public RestrictedStream(Stream stream, long length, bool leaveOpen = true) - { - this.stream = stream; - this.length = length; - this.leaveOpen = leaveOpen; - } - - public override bool CanRead - { - get - { - return true; - } - } - - public override bool CanSeek - { - get - { - return this.stream.CanSeek; - } - } - - public override bool CanWrite - { - get - { - return false; - } - } - - public override long Length - { - get - { - return this.length; - } - } - - public override long Position - { - get - { - return this.position; - } - - set - { - this.Seek(value, SeekOrigin.Begin); - } - } - - public override void Close() - { - if (!this.closed) - { - this.closed = true; - - if (!this.leaveOpen) - { - this.stream.Close(); - } - } - - base.Close(); - } - - public override int Read(byte[] buffer, int offset, int count) - { - int bytesToRead = (int)(Math.Min(this.position + count, this.length) - this.position); - - // Some streams like HttpContent.ReadOnlyStream throw InvalidOperationException - // when reading 0 bytes from huge streams. If that changes we can remove this check. - if (bytesToRead == 0) - { - return 0; - } - - int toReturn = this.stream.Read(buffer, offset, bytesToRead); - - this.position += toReturn; - - return toReturn; - } - - public override long Seek(long offset, SeekOrigin origin) - { - if (!this.stream.CanSeek) - { - throw new InvalidOperationException(); - } - - long newPosition; - - switch (origin) - { - case SeekOrigin.Begin: - newPosition = offset; - break; - - case SeekOrigin.Current: - newPosition = this.position + offset; - break; - - case SeekOrigin.End: - newPosition = this.length + offset; - break; - - default: - throw new InvalidOperationException(); - } - - newPosition = Math.Max(Math.Min(this.length, newPosition), 0); - - this.stream.Seek(newPosition - this.position, SeekOrigin.Current); - - this.position = newPosition; - - return newPosition; - } - - public override void Flush() - { - throw new NotSupportedException(); - } - - public override void SetLength(long value) - { - throw new NotSupportedException(); - } - - public override void Write(byte[] buffer, int offset, int count) - { - throw new NotSupportedException(); - } - } -} diff --git a/Scalar.Common/StreamUtil.cs b/Scalar.Common/StreamUtil.cs deleted file mode 100644 index 5774a8635a..0000000000 --- a/Scalar.Common/StreamUtil.cs +++ /dev/null @@ -1,91 +0,0 @@ -using System; -using System.IO; - -namespace Scalar.Common -{ - public class StreamUtil - { - /// - /// .NET default buffer size uses as of 8/30/16 - /// - public const int DefaultCopyBufferSize = 81920; - - /// - /// Copies all bytes from the source stream to the destination stream. This is an exact copy - /// of Stream.CopyTo(), but can uses the supplied buffer instead of allocating a new one. - /// - /// - /// As of .NET 4.6, each call to Stream.CopyTo() allocates a new 80K byte[] buffer, which - /// consumes many more resources than reusing one we already have if the scenario allows it. - /// - /// Source stream to copy from - /// Destination stream to copy to - /// - /// Shared buffer to use. If null, we allocate one with the same size .NET would otherwise use. - /// - public static void CopyToWithBuffer(Stream source, Stream destination, byte[] buffer = null) - { - buffer = buffer ?? new byte[DefaultCopyBufferSize]; - int read; - while (true) - { - try - { - read = source.Read(buffer, 0, buffer.Length); - } - catch (Exception ex) - { - // All exceptions potentially from network should be retried - throw new RetryableException("Exception while reading stream. See inner exception for details.", ex); - } - - if (read == 0) - { - break; - } - - destination.Write(buffer, 0, read); - } - } - - /// - /// Call until either bytes are read or - /// the end of is reached. - /// - /// Buffer to read bytes into. - /// Offset in to start reading into. - /// Maximum number of bytes to read. - /// - /// Number of bytes read, may be less than if end was reached. - /// - public static int TryReadGreedy(Stream stream, byte[] buf, int offset, int count) - { - int totalRead = 0; - int read = 0; - while (totalRead < count) - { - int start = offset + totalRead; - int length = count - totalRead; - - try - { - read = stream.Read(buf, start, length); - } - catch (Exception ex) - { - // All exceptions potentially from network should be retried - throw new RetryableException("Exception while reading stream. See inner exception for details.", ex); - } - - if (read == 0) - { - break; - } - - totalRead += read; - } - - return totalRead; - } - } -} diff --git a/Scalar.UnitTests/Common/DiffTreeResultTests.cs b/Scalar.UnitTests/Common/DiffTreeResultTests.cs deleted file mode 100644 index e38f6a9d95..0000000000 --- a/Scalar.UnitTests/Common/DiffTreeResultTests.cs +++ /dev/null @@ -1,371 +0,0 @@ -using NUnit.Framework; -using Scalar.Common.Git; -using Scalar.Tests.Should; -using Scalar.UnitTests.Category; -using System; -using System.IO; - -namespace Scalar.UnitTests.Common -{ - [TestFixture] - public class DiffTreeResultTests - { - private const string TestSha1 = "0ee459db639f34c3064f56845acbc7df0d528e81"; - private const string Test2Sha1 = "2052fbe2ce5b081db3e3b9ffdebe9b0258d14cce"; - private const string EmptySha1 = "0000000000000000000000000000000000000000"; - - private const string TestTreePath1 = "Test/Scalar"; - private const string TestTreePath2 = "Test/directory with blob and spaces"; - private const string TestBlobPath1 = "Test/file with spaces.txt"; - private const string TestBlobPath2 = "Test/file with tree and spaces.txt"; - - private static readonly string MissingColonLineFromDiffTree = $"040000 040000 {TestSha1} {Test2Sha1} M\t{TestTreePath1}"; - private static readonly string TooManyFieldsLineFromDiffTree = $":040000 040000 {TestSha1} {Test2Sha1} M BadData\t{TestTreePath1}"; - private static readonly string NotEnoughFieldsLineFromDiffTree = $":040000 040000 {TestSha1} {Test2Sha1}\t{TestTreePath1}"; - private static readonly string TwoPathLineFromDiffTree = $":040000 040000 {TestSha1} {Test2Sha1} M\t{TestTreePath1}\t{TestBlobPath1}"; - private static readonly string ModifyTreeLineFromDiffTree = $":040000 040000 {TestSha1} {Test2Sha1} M\t{TestTreePath1}"; - private static readonly string DeleteTreeLineFromDiffTree = $":040000 000000 {TestSha1} {EmptySha1} D\t{TestTreePath1}"; - private static readonly string AddTreeLineFromDiffTree = $":000000 040000 {EmptySha1} {Test2Sha1} A\t{TestTreePath1}"; - private static readonly string ModifyBlobLineFromDiffTree = $":100644 100644 {TestSha1} {Test2Sha1} M\t{TestBlobPath1}"; - private static readonly string DeleteBlobLineFromDiffTree = $":100755 000000 {TestSha1} {EmptySha1} D\t{TestBlobPath1}"; - private static readonly string DeleteBlobLineFromDiffTree2 = $":100644 000000 {TestSha1} {EmptySha1} D\t{TestBlobPath1}"; - private static readonly string AddBlobLineFromDiffTree = $":000000 100644 {EmptySha1} {Test2Sha1} A\t{TestBlobPath1}"; - - private static readonly string BlobLineFromLsTree = $"100644 blob {TestSha1}\t{TestTreePath1}"; - private static readonly string BlobLineWithTreePathFromLsTree = $"100644 blob {TestSha1}\t{TestBlobPath2}"; - private static readonly string TreeLineFromLsTree = $"040000 tree {TestSha1}\t{TestTreePath1}"; - private static readonly string TreeLineWithBlobPathFromLsTree = $"040000 tree {TestSha1}\t{TestTreePath2}"; - private static readonly string InvalidLineFromLsTree = $"040000 bad {TestSha1}\t{TestTreePath1}"; - private static readonly string SymLinkLineFromLsTree = $"120000 blob {TestSha1}\t{TestTreePath1}"; - - [TestCase] - [Category(CategoryConstants.ExceptionExpected)] - public void ParseFromDiffTreeLine_NullLine() - { - Assert.Throws(() => DiffTreeResult.ParseFromDiffTreeLine(null)); - } - - [TestCase] - [Category(CategoryConstants.ExceptionExpected)] - public void ParseFromDiffTreeLine_EmptyLine() - { - Assert.Throws(() => DiffTreeResult.ParseFromDiffTreeLine(string.Empty)); - } - - [TestCase] - [Category(CategoryConstants.ExceptionExpected)] - public void ParseFromDiffTreeLine_EmptyRepo() - { - DiffTreeResult expected = new DiffTreeResult() - { - Operation = DiffTreeResult.Operations.Modify, - SourceIsDirectory = true, - TargetIsDirectory = true, - TargetPath = TestTreePath1.Replace('/', Path.DirectorySeparatorChar) + Path.DirectorySeparatorChar, - SourceSha = TestSha1, - TargetSha = Test2Sha1 - }; - - DiffTreeResult result = DiffTreeResult.ParseFromDiffTreeLine(ModifyTreeLineFromDiffTree); - this.ValidateDiffTreeResult(expected, result); - } - - [TestCase] - [Category(CategoryConstants.ExceptionExpected)] - public void ParseFromLsTreeLine_NullLine() - { - Assert.Throws(() => DiffTreeResult.ParseFromLsTreeLine(null)); - } - - [TestCase] - [Category(CategoryConstants.ExceptionExpected)] - public void ParseFromLsTreeLine_EmptyLine() - { - Assert.Throws(() => DiffTreeResult.ParseFromLsTreeLine(string.Empty)); - } - - [TestCase] - public void ParseFromLsTreeLine_EmptyRepoRoot() - { - DiffTreeResult expected = new DiffTreeResult() - { - Operation = DiffTreeResult.Operations.Add, - SourceIsDirectory = false, - TargetIsDirectory = false, - TargetPath = TestTreePath1.Replace('/', Path.DirectorySeparatorChar), - SourceSha = null, - TargetSha = TestSha1 - }; - - DiffTreeResult result = DiffTreeResult.ParseFromLsTreeLine(BlobLineFromLsTree); - this.ValidateDiffTreeResult(expected, result); - } - - [TestCase] - public void ParseFromLsTreeLine_BlobLine() - { - DiffTreeResult expected = new DiffTreeResult() - { - Operation = DiffTreeResult.Operations.Add, - SourceIsDirectory = false, - TargetIsDirectory = false, - TargetPath = TestTreePath1.Replace('/', Path.DirectorySeparatorChar), - SourceSha = null, - TargetSha = TestSha1 - }; - - DiffTreeResult result = DiffTreeResult.ParseFromLsTreeLine(BlobLineFromLsTree); - this.ValidateDiffTreeResult(expected, result); - } - - [TestCase] - public void ParseFromLsTreeLine_TreeLine() - { - DiffTreeResult expected = new DiffTreeResult() - { - Operation = DiffTreeResult.Operations.Add, - SourceIsDirectory = false, - TargetIsDirectory = true, - TargetPath = CreateTreePath(TestTreePath1), - SourceSha = null, - TargetSha = null - }; - - DiffTreeResult result = DiffTreeResult.ParseFromLsTreeLine(TreeLineFromLsTree); - this.ValidateDiffTreeResult(expected, result); - } - - [TestCase] - public void ParseFromLsTreeLine_InvalidLine() - { - DiffTreeResult.ParseFromLsTreeLine(InvalidLineFromLsTree).ShouldBeNull(); - } - - [TestCase] - [Category(CategoryConstants.ExceptionExpected)] - public void ParseFromDiffTreeLine_NoColonLine() - { - Assert.Throws(() => DiffTreeResult.ParseFromDiffTreeLine(MissingColonLineFromDiffTree)); - } - - [TestCase] - [Category(CategoryConstants.ExceptionExpected)] - public void ParseFromDiffTreeLine_TooManyFieldsLine() - { - Assert.Throws(() => DiffTreeResult.ParseFromDiffTreeLine(TooManyFieldsLineFromDiffTree)); - } - - [TestCase] - [Category(CategoryConstants.ExceptionExpected)] - public void ParseFromDiffTreeLine_NotEnoughFieldsLine() - { - Assert.Throws(() => DiffTreeResult.ParseFromDiffTreeLine(NotEnoughFieldsLineFromDiffTree)); - } - - [TestCase] - - [Category(CategoryConstants.ExceptionExpected)] - public void ParseFromDiffTreeLine_TwoPathLine() - { - Assert.Throws(() => DiffTreeResult.ParseFromDiffTreeLine(TwoPathLineFromDiffTree)); - } - - [TestCase] - public void ParseFromDiffTreeLine_ModifyTreeLine() - { - DiffTreeResult expected = new DiffTreeResult() - { - Operation = DiffTreeResult.Operations.Modify, - SourceIsDirectory = true, - TargetIsDirectory = true, - TargetPath = CreateTreePath(TestTreePath1), - SourceSha = TestSha1, - TargetSha = Test2Sha1 - }; - - DiffTreeResult result = DiffTreeResult.ParseFromDiffTreeLine(ModifyTreeLineFromDiffTree); - this.ValidateDiffTreeResult(expected, result); - } - - [TestCase] - public void ParseFromDiffTreeLine_DeleteTreeLine() - { - DiffTreeResult expected = new DiffTreeResult() - { - Operation = DiffTreeResult.Operations.Delete, - SourceIsDirectory = true, - TargetIsDirectory = false, - TargetPath = CreateTreePath(TestTreePath1), - SourceSha = TestSha1, - TargetSha = EmptySha1 - }; - - DiffTreeResult result = DiffTreeResult.ParseFromDiffTreeLine(DeleteTreeLineFromDiffTree); - this.ValidateDiffTreeResult(expected, result); - } - - [TestCase] - public void ParseFromDiffTreeLine_AddTreeLine() - { - DiffTreeResult expected = new DiffTreeResult() - { - Operation = DiffTreeResult.Operations.Add, - SourceIsDirectory = false, - TargetIsDirectory = true, - TargetPath = CreateTreePath(TestTreePath1), - SourceSha = EmptySha1, - TargetSha = Test2Sha1 - }; - - DiffTreeResult result = DiffTreeResult.ParseFromDiffTreeLine(AddTreeLineFromDiffTree); - this.ValidateDiffTreeResult(expected, result); - } - - [TestCase] - public void ParseFromDiffTreeLine_AddBlobLine() - { - DiffTreeResult expected = new DiffTreeResult() - { - Operation = DiffTreeResult.Operations.Add, - SourceIsDirectory = false, - TargetIsDirectory = false, - TargetPath = TestBlobPath1.Replace('/', Path.DirectorySeparatorChar), - SourceSha = EmptySha1, - TargetSha = Test2Sha1 - }; - - DiffTreeResult result = DiffTreeResult.ParseFromDiffTreeLine(AddBlobLineFromDiffTree); - this.ValidateDiffTreeResult(expected, result); - } - - [TestCase] - public void ParseFromDiffTreeLine_DeleteBlobLine() - { - DiffTreeResult expected = new DiffTreeResult() - { - Operation = DiffTreeResult.Operations.Delete, - SourceIsDirectory = false, - TargetIsDirectory = false, - TargetPath = TestBlobPath1.Replace('/', Path.DirectorySeparatorChar), - SourceSha = TestSha1, - TargetSha = EmptySha1 - }; - - DiffTreeResult result = DiffTreeResult.ParseFromDiffTreeLine(DeleteBlobLineFromDiffTree); - this.ValidateDiffTreeResult(expected, result); - } - - [TestCase] - public void ParseFromDiffTreeLine_DeleteBlobLine2() - { - DiffTreeResult expected = new DiffTreeResult() - { - Operation = DiffTreeResult.Operations.Delete, - SourceIsDirectory = false, - TargetIsDirectory = false, - TargetPath = TestBlobPath1.Replace('/', Path.DirectorySeparatorChar), - SourceSha = TestSha1, - TargetSha = EmptySha1 - }; - - DiffTreeResult result = DiffTreeResult.ParseFromDiffTreeLine(DeleteBlobLineFromDiffTree2); - this.ValidateDiffTreeResult(expected, result); - } - - [TestCase] - public void ParseFromDiffTreeLine_ModifyBlobLine() - { - DiffTreeResult expected = new DiffTreeResult() - { - Operation = DiffTreeResult.Operations.Modify, - SourceIsDirectory = false, - TargetIsDirectory = false, - TargetPath = TestBlobPath1.Replace('/', Path.DirectorySeparatorChar), - SourceSha = TestSha1, - TargetSha = Test2Sha1 - }; - - DiffTreeResult result = DiffTreeResult.ParseFromDiffTreeLine(ModifyBlobLineFromDiffTree); - this.ValidateDiffTreeResult(expected, result); - } - - [TestCase] - public void ParseFromLsTreeLine_SymLinkLine() - { - DiffTreeResult expected = new DiffTreeResult() - { - Operation = DiffTreeResult.Operations.Add, - SourceIsDirectory = false, - TargetIsDirectory = false, - TargetIsSymLink = true, - TargetPath = TestTreePath1.Replace('/', Path.DirectorySeparatorChar), - SourceSha = null, - TargetSha = TestSha1 - }; - - DiffTreeResult result = DiffTreeResult.ParseFromLsTreeLine(SymLinkLineFromLsTree); - this.ValidateDiffTreeResult(expected, result); - } - - [TestCase] - public void ParseFromDiffTreeLine_TreeLineWithBlobPath() - { - DiffTreeResult expected = new DiffTreeResult() - { - Operation = DiffTreeResult.Operations.Add, - SourceIsDirectory = false, - TargetIsDirectory = true, - TargetPath = CreateTreePath(TestTreePath2), - SourceSha = null, - TargetSha = null - }; - - DiffTreeResult result = DiffTreeResult.ParseFromLsTreeLine(TreeLineWithBlobPathFromLsTree); - this.ValidateDiffTreeResult(expected, result); - } - - [TestCase] - public void ParseFromDiffTreeLine_BlobLineWithTreePath() - { - DiffTreeResult expected = new DiffTreeResult() - { - Operation = DiffTreeResult.Operations.Add, - SourceIsDirectory = false, - TargetIsDirectory = false, - TargetPath = TestBlobPath2.Replace('/', Path.DirectorySeparatorChar), - SourceSha = null, - TargetSha = TestSha1 - }; - - DiffTreeResult result = DiffTreeResult.ParseFromLsTreeLine(BlobLineWithTreePathFromLsTree); - this.ValidateDiffTreeResult(expected, result); - } - - [TestCase("040000 tree 73b881d52b607b0f3e9e620d36f556d3d233a11d\tScalar", DiffTreeResult.TreeMarker, true)] - [TestCase("040000 tree 73b881d52b607b0f3e9e620d36f556d3d233a11d\tScalar", DiffTreeResult.BlobMarker, false)] - [TestCase("100644 blob 44c5f5cba4b29d31c2ad06eed51ea02af76c27c0\tReadme.md", DiffTreeResult.BlobMarker, true)] - [TestCase("100755 blob 196142fbb753c0a3c7c6690323db7aa0a11f41ec\tScripts / BuildScalarForMac.sh", DiffTreeResult.BlobMarker, true)] - [TestCase("100755 blob 196142fbb753c0a3c7c6690323db7aa0a11f41ec\tScripts / BuildScalarForMac.sh", DiffTreeResult.BlobMarker, true)] - [TestCase("100755 blob 196142fbb753c0a3c7c6690323db7aa0a11f41ec\tScripts / tree file.txt", DiffTreeResult.TreeMarker, false)] - [TestCase("100755 ", DiffTreeResult.TreeMarker, false)] - public void TestGetIndexOfTypeMarker(string line, string typeMarker, bool expectedResult) - { - DiffTreeResult.IsLsTreeLineOfType(line, typeMarker).ShouldEqual(expectedResult); - } - - private static string CreateTreePath(string testPath) - { - return testPath.Replace('/', Path.DirectorySeparatorChar) + Path.DirectorySeparatorChar; - } - - private void ValidateDiffTreeResult(DiffTreeResult expected, DiffTreeResult actual) - { - actual.Operation.ShouldEqual(expected.Operation, $"{nameof(DiffTreeResult)}.{nameof(actual.Operation)}"); - actual.SourceIsDirectory.ShouldEqual(expected.SourceIsDirectory, $"{nameof(DiffTreeResult)}.{nameof(actual.SourceIsDirectory)}"); - actual.TargetIsDirectory.ShouldEqual(expected.TargetIsDirectory, $"{nameof(DiffTreeResult)}.{nameof(actual.TargetIsDirectory)}"); - actual.TargetPath.ShouldEqual(expected.TargetPath, $"{nameof(DiffTreeResult)}.{nameof(actual.TargetPath)}"); - actual.SourceSha.ShouldEqual(expected.SourceSha, $"{nameof(DiffTreeResult)}.{nameof(actual.SourceSha)}"); - actual.TargetSha.ShouldEqual(expected.TargetSha, $"{nameof(DiffTreeResult)}.{nameof(actual.TargetSha)}"); - } - } -} diff --git a/Scalar.UnitTests/Common/Git/Sha1IdTests.cs b/Scalar.UnitTests/Common/Git/Sha1IdTests.cs deleted file mode 100644 index b0ccf33992..0000000000 --- a/Scalar.UnitTests/Common/Git/Sha1IdTests.cs +++ /dev/null @@ -1,47 +0,0 @@ -using NUnit.Framework; -using Scalar.Common.Git; -using Scalar.Tests.Should; -using Scalar.UnitTests.Category; - -namespace Scalar.UnitTests.Common.Git -{ - [TestFixture] - public class Sha1IdTests - { - [TestCase] - [Category(CategoryConstants.ExceptionExpected)] - public void TryParseFailsForLowerCaseShas() - { - Sha1Id sha1; - string error; - Sha1Id.TryParse("abcdef7890123456789012345678901234567890", out sha1, out error).ShouldBeFalse(); - Sha1Id.TryParse(new string('a', 40), out sha1, out error).ShouldBeFalse(); - } - - [TestCase] - [Category(CategoryConstants.ExceptionExpected)] - public void TryParseFailsForInvalidShas() - { - Sha1Id sha1; - string error; - Sha1Id.TryParse(null, out sha1, out error).ShouldBeFalse(); - Sha1Id.TryParse("0", out sha1, out error).ShouldBeFalse(); - Sha1Id.TryParse("abcdef", out sha1, out error).ShouldBeFalse(); - Sha1Id.TryParse(new string('H', 40), out sha1, out error).ShouldBeFalse(); - } - - [TestCase] - public void TryParseSucceedsForUpperCaseShas() - { - Sha1Id sha1Id; - string error; - string sha = "ABCDEF7890123456789012345678901234567890"; - Sha1Id.TryParse(sha, out sha1Id, out error).ShouldBeTrue(); - sha1Id.ToString().ShouldEqual(sha); - - sha = new string('A', 40); - Sha1Id.TryParse(sha, out sha1Id, out error).ShouldBeTrue(); - sha1Id.ToString().ShouldEqual(sha); - } - } -} diff --git a/Scalar.UnitTests/Common/GitPathConverterTests.cs b/Scalar.UnitTests/Common/GitPathConverterTests.cs deleted file mode 100644 index cc527e6597..0000000000 --- a/Scalar.UnitTests/Common/GitPathConverterTests.cs +++ /dev/null @@ -1,56 +0,0 @@ -using NUnit.Framework; -using Scalar.Common.Git; -using Scalar.Tests.Should; - -namespace Scalar.UnitTests.Common -{ - [TestFixture] - public class GitPathConverterTests - { - private const string OctetEncoded = @"\330\261\331\212\331\204\331\214\330\243\331\203\330\252\331\210\330\250\330\261\303\273\331\205\330\247\330\261\330\263\330\243\330\272\330\263\330\267\330\263\302\272\331\260\331\260\333\202\331\227\331\222\333\265\330\261\331\212\331\204\331\214\330\243\331\203"; - private const string Utf8Encoded = @"ريلٌأكتوبرûمارسأغسطسºٰٰۂْٗ۵ريلٌأك"; - private const string TestPath = @"/Scalar/"; - - [TestCase] - public void NullFilepathTest() - { - GitPathConverter.ConvertPathOctetsToUtf8(null).ShouldEqual(null); - } - - [TestCase] - public void EmptyFilepathTest() - { - GitPathConverter.ConvertPathOctetsToUtf8(string.Empty).ShouldEqual(string.Empty); - } - - [TestCase] - public void FilepathWithoutOctets() - { - GitPathConverter.ConvertPathOctetsToUtf8(TestPath + "test.cs").ShouldEqual(TestPath + "test.cs"); - } - - [TestCase] - public void FilepathWithoutOctetsAsFilename() - { - GitPathConverter.ConvertPathOctetsToUtf8(TestPath + OctetEncoded).ShouldEqual(TestPath + Utf8Encoded); - } - - [TestCase] - public void FilepathWithoutOctetsAsFilenameNoExtension() - { - GitPathConverter.ConvertPathOctetsToUtf8(TestPath + OctetEncoded + ".txt").ShouldEqual(TestPath + Utf8Encoded + ".txt"); - } - - [TestCase] - public void FilepathWithoutOctetsAsFolder() - { - GitPathConverter.ConvertPathOctetsToUtf8(TestPath + OctetEncoded + "/file.txt").ShouldEqual(TestPath + Utf8Encoded + "/file.txt"); - } - - [TestCase] - public void FilepathWithoutOctetsAsFileAndFolder() - { - GitPathConverter.ConvertPathOctetsToUtf8(TestPath + OctetEncoded + TestPath + OctetEncoded + ".txt").ShouldEqual(TestPath + Utf8Encoded + TestPath + Utf8Encoded + ".txt"); - } - } -} diff --git a/Scalar.UnitTests/Common/RefLogEntryTests.cs b/Scalar.UnitTests/Common/RefLogEntryTests.cs deleted file mode 100644 index 86b3ef970c..0000000000 --- a/Scalar.UnitTests/Common/RefLogEntryTests.cs +++ /dev/null @@ -1,63 +0,0 @@ -using NUnit.Framework; -using Scalar.Common.Git; -using Scalar.Tests.Should; - -namespace Scalar.UnitTests.Common -{ - [TestFixture] - public class RefLogEntryTests - { - [TestCase] - public void ParsesValidRefLog() - { - const string SourceSha = "0000000000000000000000000000000000000000"; - const string TargetSha = "d249e0fea84484eb105d52174cf326958ee87ab4"; - const string Reason = "clone: from https://repourl"; - string testLine = string.Format("{0} {1} author 1478738341 -0800\t{2}", SourceSha, TargetSha, Reason); - - RefLogEntry output; - RefLogEntry.TryParse(testLine, out output).ShouldEqual(true); - - output.ShouldNotBeNull(); - output.SourceSha.ShouldEqual(SourceSha); - output.TargetSha.ShouldEqual(TargetSha); - output.Reason.ShouldEqual(Reason); - } - - [TestCase] - public void FailsForMissingReason() - { - const string SourceSha = "0000000000000000000000000000000000000000"; - const string TargetSha = "d249e0fea84484eb105d52174cf326958ee87ab4"; - string testLine = string.Format("{0} {1} author 1478738341 -0800", SourceSha, TargetSha); - - RefLogEntry output; - RefLogEntry.TryParse(testLine, out output).ShouldEqual(false); - - output.ShouldBeNull(); - } - - [TestCase] - public void FailsForMissingTargetSha() - { - const string SourceSha = "0000000000000000000000000000000000000000"; - string testLine = string.Format("{0} ", SourceSha); - - RefLogEntry output; - RefLogEntry.TryParse(testLine, out output).ShouldEqual(false); - - output.ShouldBeNull(); - } - - [TestCase] - public void FailsForNull() - { - string testLine = null; - - RefLogEntry output; - RefLogEntry.TryParse(testLine, out output).ShouldEqual(false); - - output.ShouldBeNull(); - } - } -}