copy files and direct restore and build without adjusting paths
This commit is contained in:
		
					parent
					
						
							
								4952a819d4
							
						
					
				
			
			
				commit
				
					
						f77c5d76cb
					
				
			
		
					 2 changed files with 161 additions and 368 deletions
				
			
		|  | @ -18,33 +18,15 @@ namespace Microsoft.DotNet.TestFramework | ||||||
| { | { | ||||||
|     public class TestAssetInfo |     public class TestAssetInfo | ||||||
|     { |     { | ||||||
|         private const string DataDirectoryName = ".tam"; |  | ||||||
| 
 |  | ||||||
|         private readonly string [] FilesToExclude = { ".DS_Store", ".noautobuild" }; |         private readonly string [] FilesToExclude = { ".DS_Store", ".noautobuild" }; | ||||||
| 
 | 
 | ||||||
|         private readonly DirectoryInfo [] _directoriesToExclude; |         public string AssetName { get; private set; } | ||||||
| 
 | 
 | ||||||
|         private readonly string _assetName; |         public FileInfo DotnetExeFile { get; private set; } | ||||||
| 
 | 
 | ||||||
|         private readonly DirectoryInfo _dataDirectory; |         public string ProjectFilePattern { get; private set; } | ||||||
| 
 | 
 | ||||||
|         private readonly DirectoryInfo _root; |         public DirectoryInfo Root { get; private set; } | ||||||
| 
 |  | ||||||
|         private readonly DirectoryInfo _operationDirectory; |  | ||||||
| 
 |  | ||||||
|         private readonly TestAssetInventoryFiles _inventoryFiles; |  | ||||||
| 
 |  | ||||||
|         private readonly FileInfo _dotnetExeFile; |  | ||||||
| 
 |  | ||||||
|         private readonly string _projectFilePattern; |  | ||||||
| 
 |  | ||||||
|         internal DirectoryInfo Root  |  | ||||||
|         { |  | ||||||
|             get |  | ||||||
|             { |  | ||||||
|                 return _operationDirectory; |  | ||||||
|             } |  | ||||||
|         } |  | ||||||
| 
 | 
 | ||||||
|         internal TestAssetInfo(DirectoryInfo root, string assetName, FileInfo dotnetExeFile, string projectFilePattern) |         internal TestAssetInfo(DirectoryInfo root, string assetName, FileInfo dotnetExeFile, string projectFilePattern) | ||||||
|         { |         { | ||||||
|  | @ -68,24 +50,13 @@ namespace Microsoft.DotNet.TestFramework | ||||||
|                 throw new ArgumentException("Argument cannot be null or whitespace", nameof(projectFilePattern)); |                 throw new ArgumentException("Argument cannot be null or whitespace", nameof(projectFilePattern)); | ||||||
|             } |             } | ||||||
| 
 | 
 | ||||||
|             _root = root; |             Root = root; | ||||||
| 
 | 
 | ||||||
|             _assetName = assetName; |             AssetName = assetName; | ||||||
| 
 | 
 | ||||||
|             _dotnetExeFile = dotnetExeFile; |             DotnetExeFile = dotnetExeFile; | ||||||
| 
 | 
 | ||||||
|             _projectFilePattern = projectFilePattern; |             ProjectFilePattern = projectFilePattern; | ||||||
| 
 |  | ||||||
|             _dataDirectory = _root.GetDirectory(DataDirectoryName); |  | ||||||
| 
 |  | ||||||
|             _operationDirectory = _dataDirectory.GetDirectory("files"); |  | ||||||
| 
 |  | ||||||
|             _inventoryFiles = new TestAssetInventoryFiles(_dataDirectory); |  | ||||||
| 
 |  | ||||||
|             _directoriesToExclude = new [] |  | ||||||
|             { |  | ||||||
|                 _dataDirectory |  | ||||||
|             }; |  | ||||||
| 
 | 
 | ||||||
|             //throw new Exception($"root = {_root}\nassetName = {_assetName}\ndotnetExeFile = {_dotnetExeFile}\nprojectFilePattern = {_projectFilePattern}\ndataDir = {_dataDirectory}\ndirectoriesToExclude = {string.Join<DirectoryInfo>(";",_directoriesToExclude)}"); |             //throw new Exception($"root = {_root}\nassetName = {_assetName}\ndotnetExeFile = {_dotnetExeFile}\nprojectFilePattern = {_projectFilePattern}\ndataDir = {_dataDirectory}\ndirectoriesToExclude = {string.Join<DirectoryInfo>(";",_directoriesToExclude)}"); | ||||||
|         } |         } | ||||||
|  | @ -103,37 +74,8 @@ namespace Microsoft.DotNet.TestFramework | ||||||
|         { |         { | ||||||
|             ThrowIfTestAssetDoesNotExist(); |             ThrowIfTestAssetDoesNotExist(); | ||||||
| 
 | 
 | ||||||
|             RemoveCacheIfSourcesHaveChanged(); |             return Root.GetFiles("*.*", SearchOption.AllDirectories) | ||||||
|              |                         .Where(f => !FilesToExclude.Contains(f.Name)); | ||||||
|             return GetInventory( |  | ||||||
|                 _inventoryFiles.Source, |  | ||||||
|                 null, |  | ||||||
|                 DoCopyFiles); |  | ||||||
|         } |  | ||||||
| 
 |  | ||||||
|         internal IEnumerable<FileInfo> GetRestoreFiles() |  | ||||||
|         { |  | ||||||
|             ThrowIfTestAssetDoesNotExist(); |  | ||||||
| 
 |  | ||||||
|             RemoveCacheIfSourcesHaveChanged(); |  | ||||||
|              |  | ||||||
|             return GetInventory( |  | ||||||
|                 _inventoryFiles.Restore,  |  | ||||||
|                 GetSourceFiles,  |  | ||||||
|                 DoRestore); |  | ||||||
|         } |  | ||||||
| 
 |  | ||||||
|         internal IEnumerable<FileInfo> GetBuildFiles() |  | ||||||
|         { |  | ||||||
|             ThrowIfTestAssetDoesNotExist(); |  | ||||||
| 
 |  | ||||||
|             RemoveCacheIfSourcesHaveChanged(); |  | ||||||
|              |  | ||||||
|             return GetInventory( |  | ||||||
|                 _inventoryFiles.Build, |  | ||||||
|                 () => GetRestoreFiles() |  | ||||||
|                         .Concat(GetSourceFiles()), // TODO: likely not needed |  | ||||||
|                 DoBuild); |  | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|         private DirectoryInfo GetTestDestinationDirectory(string callingMethod, string identifier) |         private DirectoryInfo GetTestDestinationDirectory(string callingMethod, string identifier) | ||||||
|  | @ -143,56 +85,7 @@ namespace Microsoft.DotNet.TestFramework | ||||||
| #else | #else | ||||||
|             string baseDirectory = AppContext.BaseDirectory; |             string baseDirectory = AppContext.BaseDirectory; | ||||||
| #endif | #endif | ||||||
|             return new DirectoryInfo(Path.Combine(baseDirectory, callingMethod + identifier, _assetName)); |             return new DirectoryInfo(Path.Combine(baseDirectory, callingMethod + identifier, AssetName)); | ||||||
|         } |  | ||||||
| 
 |  | ||||||
|         private IEnumerable<FileInfo> GetOperationFileList() |  | ||||||
|         { |  | ||||||
|             return _operationDirectory.GetFiles("*.*", SearchOption.AllDirectories); |  | ||||||
|         } |  | ||||||
| 
 |  | ||||||
|         private IEnumerable<FileInfo> GetOriginalFileList() |  | ||||||
|         { |  | ||||||
|             return _root.GetFiles("*.*", SearchOption.AllDirectories) |  | ||||||
|                         .Where(f => !_directoriesToExclude.Any(d => d.Contains(f))) |  | ||||||
|                         .Where(f => !FilesToExclude.Contains(f.Name));     |  | ||||||
|         } |  | ||||||
| 
 |  | ||||||
|         private IEnumerable<FileInfo> GetInventory( |  | ||||||
|             FileInfo file, |  | ||||||
|             Func<IEnumerable<FileInfo>> beforeAction, |  | ||||||
|             Action action) |  | ||||||
|         { |  | ||||||
|             var inventory = Enumerable.Empty<FileInfo>(); |  | ||||||
| 
 |  | ||||||
|             IEnumerable<FileInfo> preInventory; |  | ||||||
| 
 |  | ||||||
|             if (beforeAction == null) |  | ||||||
|             { |  | ||||||
|                 preInventory = new List<FileInfo>(); |  | ||||||
|             } |  | ||||||
|             else |  | ||||||
|             { |  | ||||||
|                 preInventory = beforeAction(); |  | ||||||
|             } |  | ||||||
| 
 |  | ||||||
|             ExclusiveFolderAccess.Do(_dataDirectory, (folder) => { |  | ||||||
|                 file.Refresh(); |  | ||||||
|                 if (file.Exists) |  | ||||||
|                 { |  | ||||||
|                     inventory = folder.LoadInventory(file); |  | ||||||
|                 } |  | ||||||
|                 else |  | ||||||
|                 { |  | ||||||
|                     action(); |  | ||||||
| 
 |  | ||||||
|                     inventory = GetOperationFileList().Where(i => !preInventory.Select(p => p.FullName).Contains(i.FullName)); |  | ||||||
| 
 |  | ||||||
|                     folder.SaveInventory(file, inventory); |  | ||||||
|                 } |  | ||||||
|             }); |  | ||||||
| 
 |  | ||||||
|             return inventory; |  | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|         private static string RebasePath(string path, string oldBaseDirectory, string newBaseDirectory) |         private static string RebasePath(string path, string oldBaseDirectory, string newBaseDirectory) | ||||||
|  | @ -201,19 +94,6 @@ namespace Microsoft.DotNet.TestFramework | ||||||
|             return Path.Combine(newBaseDirectory, path); |             return Path.Combine(newBaseDirectory, path); | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|         private void RemoveOperationFiles() |  | ||||||
|         { |  | ||||||
|             foreach (var opFile in GetOperationFileList()) |  | ||||||
|             { |  | ||||||
|                 opFile.Delete(); |  | ||||||
|             } |  | ||||||
| 
 |  | ||||||
|             foreach (var f in _inventoryFiles.AllInventoryFiles) |  | ||||||
|             { |  | ||||||
|                 f.Delete(); |  | ||||||
|             } |  | ||||||
|         } |  | ||||||
| 
 |  | ||||||
|         private bool IsAncestor(FileInfo file, DirectoryInfo maybeAncestor) |         private bool IsAncestor(FileInfo file, DirectoryInfo maybeAncestor) | ||||||
|         { |         { | ||||||
|             var dir = file.Directory; |             var dir = file.Directory; | ||||||
|  | @ -231,240 +111,69 @@ namespace Microsoft.DotNet.TestFramework | ||||||
|             return false; |             return false; | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|         private void DoCopyFiles() |         //private void DoCopyFiles() | ||||||
|         { |         //{ | ||||||
|             Console.WriteLine($"TestAsset CopyFiles '{_assetName}'"); |         //    Console.WriteLine($"TestAsset CopyFiles '{AssetName}'"); | ||||||
| 
 | 
 | ||||||
|             _operationDirectory.Refresh(); |         //    _operationDirectory.Refresh(); | ||||||
|             if (!_operationDirectory.Exists) |         //    if (!_operationDirectory.Exists) | ||||||
|             { |         //    { | ||||||
|                 _operationDirectory.Create(); |         //        _operationDirectory.Create(); | ||||||
|             } |         //    } | ||||||
|             else |         //    else | ||||||
|             { |         //    { | ||||||
|                 if (_operationDirectory.GetFiles().Any()) |         //        if (_operationDirectory.GetFiles().Any()) | ||||||
|                 { |         //        { | ||||||
|                     throw new Exception("operation files folder not empty"); |         //            throw new Exception("operation files folder not empty"); | ||||||
|                 } |         //        } | ||||||
|             } |         //    } | ||||||
| 
 | 
 | ||||||
|             foreach (var f in GetOriginalFileList()) |         //    foreach (var f in GetOriginalFileList()) | ||||||
|             { |         //    { | ||||||
|                 string destinationPath = RebasePath(f.FullName, _root.FullName, _operationDirectory.FullName); |         //        string destinationPath = RebasePath(f.FullName, Root.FullName, _operationDirectory.FullName); | ||||||
|                 var destinationDir = new FileInfo(destinationPath).Directory; |         //        var destinationDir = new FileInfo(destinationPath).Directory; | ||||||
|                 if (!destinationDir.Exists) |         //        if (!destinationDir.Exists) | ||||||
|                 { |         //        { | ||||||
|                     destinationDir.Create(); |         //            destinationDir.Create(); | ||||||
|                 } |         //        } | ||||||
|                 if (string.Equals(f.Name, "nuget.config", StringComparison.OrdinalIgnoreCase)) |         //        if (string.Equals(f.Name, "nuget.config", StringComparison.OrdinalIgnoreCase)) | ||||||
|                 { |         //        { | ||||||
|                     var doc = XDocument.Load(f.FullName, LoadOptions.PreserveWhitespace); |         //            var doc = XDocument.Load(f.FullName, LoadOptions.PreserveWhitespace); | ||||||
|                     foreach (var v in doc.Root.Element("packageSources").Elements("add").Attributes("value")) |         //            foreach (var v in doc.Root.Element("packageSources").Elements("add").Attributes("value")) | ||||||
|                     { |         //            { | ||||||
|                         if (!Path.IsPathRooted(v.Value)) |         //                if (!Path.IsPathRooted(v.Value)) | ||||||
|                         { |         //                { | ||||||
|                             string fullPath = Path.GetFullPath(Path.Combine(f.Directory.FullName, v.Value)); |         //                    string fullPath = Path.GetFullPath(Path.Combine(f.Directory.FullName, v.Value)); | ||||||
|                             if (!IsAncestor(new FileInfo(fullPath), _root)) |         //                    if (!IsAncestor(new FileInfo(fullPath), Root)) | ||||||
|                             { |         //                    { | ||||||
|                                 v.Value = fullPath; |         //                        v.Value = fullPath; | ||||||
|                             } |         //                    } | ||||||
|                         } |         //                } | ||||||
|                          |                          | ||||||
|                         //throw new Exception($"\nvalue = {v.Value}\n" + |         //                //throw new Exception($"\nvalue = {v.Value}\n" + | ||||||
|                         //    $"f.dir = {f.Directory.FullName}\n" + |         //                //    $"f.dir = {f.Directory.FullName}\n" + | ||||||
|                         //    $"fullPath = {fullPath}"); |         //                //    $"fullPath = {fullPath}"); | ||||||
|                          |                          | ||||||
|                     } |         //            } | ||||||
| 
 | 
 | ||||||
|                     using (var file = new FileStream(destinationPath, FileMode.CreateNew, FileAccess.ReadWrite)) |         //            using (var file = new FileStream(destinationPath, FileMode.CreateNew, FileAccess.ReadWrite)) | ||||||
|                     { |         //            { | ||||||
|                         doc.Save(file, SaveOptions.None); |         //                doc.Save(file, SaveOptions.None); | ||||||
|                     } |         //            } | ||||||
|                 } |         //        } | ||||||
|                 else |         //        else | ||||||
|                 { |         //        { | ||||||
|                     f.CopyTo(destinationPath); |         //            f.CopyTo(destinationPath); | ||||||
|                 } |         //        } | ||||||
|             } |         //    } | ||||||
|         } |         //} | ||||||
| 
 | 
 | ||||||
|         private void DoRestore() |  | ||||||
|         { |  | ||||||
|             //throw new Exception("foooooo"); |  | ||||||
|             try |  | ||||||
|             { |  | ||||||
|                 Console.WriteLine($"TestAsset Restore '{_assetName}'"); |  | ||||||
| 
 |  | ||||||
|                 _operationDirectory.Refresh(); |  | ||||||
|                 var projFiles = _operationDirectory.GetFiles(_projectFilePattern, SearchOption.AllDirectories); |  | ||||||
| 
 |  | ||||||
|                 foreach (var projFile in projFiles) |  | ||||||
|                 { |  | ||||||
|                     var restoreArgs = new string[] { "restore", projFile.FullName }; |  | ||||||
| 
 |  | ||||||
|                     var commandResult = Command.Create(_dotnetExeFile.FullName, restoreArgs) |  | ||||||
|                                         .CaptureStdOut() |  | ||||||
|                                         .CaptureStdErr() |  | ||||||
|                                         .Execute(); |  | ||||||
| 
 |  | ||||||
|                     int exitCode = commandResult.ExitCode; |  | ||||||
| 
 |  | ||||||
|                     if (exitCode != 0) |  | ||||||
|                     { |  | ||||||
|                         Console.WriteLine(commandResult.StdOut); |  | ||||||
| 
 |  | ||||||
|                         Console.WriteLine(commandResult.StdErr); |  | ||||||
| 
 |  | ||||||
|                         string message = string.Format($"TestAsset Restore '{_assetName}'@'{projFile.FullName}' Failed with {exitCode}"); |  | ||||||
| 
 |  | ||||||
|                         throw new Exception($"TestAsset {_dotnetExeFile.FullName} {string.Join(" ", restoreArgs)}"); |  | ||||||
|                     } |  | ||||||
|                 } |  | ||||||
|             } |  | ||||||
|             catch (Exception e) |  | ||||||
|             { |  | ||||||
|                 throw new Exception($"NOOOOOOOOOOOOOOOOOOOOOOOOOOOOO:\n{e.Message}"); |  | ||||||
|             } |  | ||||||
|         } |  | ||||||
| 
 |  | ||||||
|         private void DoBuild() |  | ||||||
|         { |  | ||||||
|             string[] args = new string[] { "build" }; |  | ||||||
| 
 |  | ||||||
|             Console.WriteLine($"TestAsset Build '{_assetName}'"); |  | ||||||
| 
 |  | ||||||
|             var commandResult = Command.Create(_dotnetExeFile.FullName, args)  |  | ||||||
|                                     .WorkingDirectory(_operationDirectory.FullName) |  | ||||||
|                                     .CaptureStdOut() |  | ||||||
|                                     .CaptureStdErr() |  | ||||||
|                                     .Execute(); |  | ||||||
| 
 |  | ||||||
|             int exitCode = commandResult.ExitCode; |  | ||||||
| 
 |  | ||||||
|             if (exitCode != 0) |  | ||||||
|             { |  | ||||||
|                 Console.WriteLine(commandResult.StdOut); |  | ||||||
| 
 |  | ||||||
|                 Console.WriteLine(commandResult.StdErr); |  | ||||||
| 
 |  | ||||||
|                 string message = string.Format($"TestAsset Build '{_assetName}' Failed with {exitCode}"); |  | ||||||
|                  |  | ||||||
|                 throw new Exception(message); |  | ||||||
|             } |  | ||||||
|         } |  | ||||||
| 
 |  | ||||||
|         private bool HaveSourcesChanged(ExclusiveFolderAccess folder) |  | ||||||
|         { |  | ||||||
|             var originalFiles = GetOriginalFileList(); |  | ||||||
|             var originalFilesRebased = originalFiles.Select(f => RebasePath(f.FullName, _root.FullName, _operationDirectory.FullName)); |  | ||||||
|             var trackedOriginalFiles = folder.LoadInventory(_inventoryFiles.Source); |  | ||||||
| 
 |  | ||||||
|             bool hasUntrackedFiles = originalFilesRebased.Any(a => !trackedOriginalFiles.Any(t => t.FullName.Equals(a))); |  | ||||||
|             if (hasUntrackedFiles) |  | ||||||
|             { |  | ||||||
|                 return true; |  | ||||||
|             } |  | ||||||
| 
 |  | ||||||
|             bool hasMissingFiles = trackedOriginalFiles.Any(t => !File.Exists(RebasePath(t.FullName, _operationDirectory.FullName, _root.FullName))); |  | ||||||
|             if (hasMissingFiles) |  | ||||||
|             { |  | ||||||
|                 return true; |  | ||||||
|             } |  | ||||||
| 
 |  | ||||||
|             foreach (var origFile in originalFiles) |  | ||||||
|             { |  | ||||||
|                 var copiedFile = new FileInfo(RebasePath(origFile.FullName, _root.FullName, _operationDirectory.FullName)); |  | ||||||
|                 if (origFile.LastWriteTimeUtc != copiedFile.LastWriteTimeUtc) |  | ||||||
|                 { |  | ||||||
|                     return true; |  | ||||||
|                 } |  | ||||||
|             } |  | ||||||
| 
 |  | ||||||
|             return false; |  | ||||||
|         } |  | ||||||
| 
 |  | ||||||
|         private void RemoveCacheIfSourcesHaveChanged() |  | ||||||
|         { |  | ||||||
|             ExclusiveFolderAccess.Do(_dataDirectory, (folder) => { |  | ||||||
|                 _operationDirectory.Refresh(); |  | ||||||
|                 if (!_operationDirectory.Exists) |  | ||||||
|                 { |  | ||||||
|                     return; |  | ||||||
|                 } |  | ||||||
| 
 |  | ||||||
|                 if (HaveSourcesChanged(folder)) |  | ||||||
|                 { |  | ||||||
|                     Console.WriteLine("Sources have changed................................"); |  | ||||||
|                     RemoveOperationFiles(); |  | ||||||
|                 } |  | ||||||
|             }); |  | ||||||
|         } |  | ||||||
| 
 | 
 | ||||||
|         private void ThrowIfTestAssetDoesNotExist() |         private void ThrowIfTestAssetDoesNotExist() | ||||||
|         { |         { | ||||||
|             if (!_root.Exists) |             if (!Root.Exists) | ||||||
|             {  |             {  | ||||||
|                 throw new DirectoryNotFoundException($"Directory not found at '{_root.FullName}'");  |                 throw new DirectoryNotFoundException($"Directory not found at '{Root.FullName}'");  | ||||||
|             }  |  | ||||||
|         } |  | ||||||
| 
 |  | ||||||
|         private class ExclusiveFolderAccess |  | ||||||
|         { |  | ||||||
|             private DirectoryInfo _directory; |  | ||||||
| 
 |  | ||||||
|             private ExclusiveFolderAccess(DirectoryInfo directory) |  | ||||||
|             { |  | ||||||
|                 _directory = directory; |  | ||||||
|             } |  | ||||||
| 
 |  | ||||||
|             public static void Do(DirectoryInfo directory, Action<ExclusiveFolderAccess> action) |  | ||||||
|             { |  | ||||||
|                 Task.Run(async () => await ConcurrencyUtilities.ExecuteWithFileLockedAsync<object>( |  | ||||||
|                     directory.FullName,  |  | ||||||
|                     lockedToken => |  | ||||||
|                     { |  | ||||||
|                         action(new ExclusiveFolderAccess(directory)); |  | ||||||
|                         return Task.FromResult(new Object()); |  | ||||||
|                     }, |  | ||||||
|                     CancellationToken.None)).Wait(); |  | ||||||
|             } |  | ||||||
| 
 |  | ||||||
|             public static IEnumerable<FileInfo> Read(FileInfo file) |  | ||||||
|             { |  | ||||||
|                 IEnumerable<FileInfo> ret = null; |  | ||||||
|                 Do(file.Directory, (folder) => { |  | ||||||
|                     ret = folder.LoadInventory(file); |  | ||||||
|                 }); |  | ||||||
| 
 |  | ||||||
|                 return ret; |  | ||||||
|             } |  | ||||||
| 
 |  | ||||||
|             public IEnumerable<FileInfo> LoadInventory(FileInfo file) |  | ||||||
|             { |  | ||||||
|                 file.Refresh(); |  | ||||||
|                 if (!file.Exists) |  | ||||||
|                 { |  | ||||||
|                     return Enumerable.Empty<FileInfo>(); |  | ||||||
|                 } |  | ||||||
| 
 |  | ||||||
|                 var inventory = new List<FileInfo>(); |  | ||||||
|                 foreach (var p in File.ReadAllLines(file.FullName)) |  | ||||||
|                 { |  | ||||||
|                     inventory.Add(new FileInfo(p)); |  | ||||||
|                 } |  | ||||||
| 
 |  | ||||||
|                 return inventory; |  | ||||||
|             } |  | ||||||
| 
 |  | ||||||
|             public void SaveInventory(FileInfo file, IEnumerable<FileInfo> inventory) |  | ||||||
|             { |  | ||||||
|                 _directory.Refresh(); |  | ||||||
|                 if (!_directory.Exists) |  | ||||||
|                 { |  | ||||||
|                     _directory.Create(); |  | ||||||
|                 } |  | ||||||
| 
 |  | ||||||
|                 File.WriteAllLines(file.FullName, inventory.Select((fi) => fi.FullName).ToList()); |  | ||||||
|             }  |             }  | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
|  |  | ||||||
|  | @ -17,6 +17,18 @@ namespace Microsoft.DotNet.TestFramework | ||||||
| { | { | ||||||
|     public class TestAssetInstance |     public class TestAssetInstance | ||||||
|     { |     { | ||||||
|  |         public DirectoryInfo MigrationBackupRoot { get; } | ||||||
|  | 
 | ||||||
|  |         public DirectoryInfo Root { get; } | ||||||
|  | 
 | ||||||
|  |         public TestAssetInfo TestAssetInfo { get; } | ||||||
|  | 
 | ||||||
|  |         private bool _filesCopied = false; | ||||||
|  | 
 | ||||||
|  |         private bool _restored = false; | ||||||
|  | 
 | ||||||
|  |         private bool _built = false; | ||||||
|  | 
 | ||||||
|         public TestAssetInstance(TestAssetInfo testAssetInfo, DirectoryInfo root) |         public TestAssetInstance(TestAssetInfo testAssetInfo, DirectoryInfo root) | ||||||
|         { |         { | ||||||
|             if (testAssetInfo == null) |             if (testAssetInfo == null) | ||||||
|  | @ -48,36 +60,44 @@ namespace Microsoft.DotNet.TestFramework | ||||||
|             } |             } | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|         public DirectoryInfo MigrationBackupRoot { get; } |  | ||||||
| 
 |  | ||||||
|         public DirectoryInfo Root { get; } |  | ||||||
| 
 |  | ||||||
|         public TestAssetInfo TestAssetInfo { get; } |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
|         public TestAssetInstance WithSourceFiles() |         public TestAssetInstance WithSourceFiles() | ||||||
|         { |         { | ||||||
|             var filesToCopy = TestAssetInfo.GetSourceFiles(); |             if (!_filesCopied) | ||||||
|  |             { | ||||||
|  |                 var filesToCopy = TestAssetInfo.GetSourceFiles(); | ||||||
| 
 | 
 | ||||||
|             CopyFiles(filesToCopy); |                 CopyFiles(filesToCopy); | ||||||
|  | 
 | ||||||
|  |                 _filesCopied = true; | ||||||
|  |             } | ||||||
| 
 | 
 | ||||||
|             return this; |             return this; | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|         public TestAssetInstance WithRestoreFiles() |         public TestAssetInstance WithRestoreFiles() | ||||||
|         { |         { | ||||||
|             var filesToCopy = TestAssetInfo.GetRestoreFiles(); |             if (!_restored) | ||||||
|  |             { | ||||||
|  |                 WithSourceFiles(); | ||||||
| 
 | 
 | ||||||
|             CopyFiles(filesToCopy); |                 RestoreAllProjects(); | ||||||
|  | 
 | ||||||
|  |                 _restored = true; | ||||||
|  |             } | ||||||
| 
 | 
 | ||||||
|             return this; |             return this; | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|         public TestAssetInstance WithBuildFiles() |         public TestAssetInstance WithBuildFiles() | ||||||
|         { |         { | ||||||
|             var filesToCopy = TestAssetInfo.GetBuildFiles(); |             if (!_built) | ||||||
|  |             { | ||||||
|  |                 WithRestoreFiles(); | ||||||
| 
 | 
 | ||||||
|             CopyFiles(filesToCopy); |                 BuildRootProjectOrSolution(); | ||||||
|  | 
 | ||||||
|  |                 _built = true; | ||||||
|  |             } | ||||||
| 
 | 
 | ||||||
|             return this; |             return this; | ||||||
|         } |         } | ||||||
|  | @ -171,5 +191,69 @@ namespace Microsoft.DotNet.TestFramework | ||||||
|                 file.CopyTo(newPath); |                 file.CopyTo(newPath); | ||||||
|             } |             } | ||||||
|         } |         } | ||||||
|  | 
 | ||||||
|  |         private void BuildRootProjectOrSolution() | ||||||
|  |         { | ||||||
|  |             string[] args = new string[] { "build" }; | ||||||
|  | 
 | ||||||
|  |             Console.WriteLine($"TestAsset Build '{TestAssetInfo.AssetName}'"); | ||||||
|  | 
 | ||||||
|  |             var commandResult = Command.Create(TestAssetInfo.DotnetExeFile.FullName, args) | ||||||
|  |                                     .WorkingDirectory(Root.FullName) | ||||||
|  |                                     .CaptureStdOut() | ||||||
|  |                                     .CaptureStdErr() | ||||||
|  |                                     .Execute(); | ||||||
|  | 
 | ||||||
|  |             int exitCode = commandResult.ExitCode; | ||||||
|  | 
 | ||||||
|  |             if (exitCode != 0) | ||||||
|  |             { | ||||||
|  |                 Console.WriteLine(commandResult.StdOut); | ||||||
|  | 
 | ||||||
|  |                 Console.WriteLine(commandResult.StdErr); | ||||||
|  | 
 | ||||||
|  |                 string message = string.Format($"TestAsset Build '{TestAssetInfo.AssetName}' Failed with {exitCode}"); | ||||||
|  | 
 | ||||||
|  |                 throw new Exception(message); | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         private IEnumerable<FileInfo> GetProjectFiles() | ||||||
|  |         { | ||||||
|  |             return Root.GetFiles(TestAssetInfo.ProjectFilePattern, SearchOption.AllDirectories); | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         private void Restore(FileInfo projectFile) | ||||||
|  |         { | ||||||
|  |             var restoreArgs = new string[] { "restore", projectFile.FullName }; | ||||||
|  | 
 | ||||||
|  |             var commandResult = Command.Create(TestAssetInfo.DotnetExeFile.FullName, restoreArgs) | ||||||
|  |                                 .CaptureStdOut() | ||||||
|  |                                 .CaptureStdErr() | ||||||
|  |                                 .Execute(); | ||||||
|  | 
 | ||||||
|  |             int exitCode = commandResult.ExitCode; | ||||||
|  | 
 | ||||||
|  |             if (exitCode != 0) | ||||||
|  |             { | ||||||
|  |                 Console.WriteLine(commandResult.StdOut); | ||||||
|  | 
 | ||||||
|  |                 Console.WriteLine(commandResult.StdErr); | ||||||
|  | 
 | ||||||
|  |                 string message = string.Format($"TestAsset Restore '{TestAssetInfo.AssetName}'@'{projectFile.FullName}' Failed with {exitCode}"); | ||||||
|  | 
 | ||||||
|  |                 throw new Exception($"TestAsset {TestAssetInfo.DotnetExeFile.FullName} {string.Join(" ", restoreArgs)}"); | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         private void RestoreAllProjects() | ||||||
|  |         { | ||||||
|  |             Console.WriteLine($"TestAsset Restore '{TestAssetInfo.AssetName}'"); | ||||||
|  | 
 | ||||||
|  |             foreach (var projFile in GetProjectFiles()) | ||||||
|  |             { | ||||||
|  |                 Restore(projFile); | ||||||
|  |             } | ||||||
|  |         } | ||||||
|     } |     } | ||||||
| } | } | ||||||
|  |  | ||||||
		Reference in a new issue
	
	 Krzysztof Wicher
				Krzysztof Wicher