public void AddProject(ProjectCreator creator, string path)
        {
            string normalizedPath = TestRepoUtils.NormalizePath(path);
            string targetFileName = Path.Combine(TestRepoRoot, normalizedPath);

            creator.Save(targetFileName);
        }
 public static string GetTestInputPath(string relativeTestInputPath)
 {
     return(Path.Combine(
                Path.GetDirectoryName(typeof(TestRepoBuilder).Assembly.Location),
                "inputs",
                TestRepoUtils.NormalizePath(relativeTestInputPath)));
 }
 public void Dispose()
 {
     if (string.IsNullOrEmpty(CommonRoot) && Directory.Exists(CommonRoot))
     {
         TestRepoUtils.KillSpecificExecutable(Path.Combine(CommonDotnetRoot, TestRepoUtils.DotNetHostExecutableName));
         // Delete the main root
         Directory.Delete(Directory.GetParent(CommonRoot).FullName, true);
     }
 }
        private async Task AddFileWithContents(string path, string contents)
        {
            string normalizedPath = TestRepoUtils.NormalizePath(path);
            string targetFileName = Path.Combine(TestRepoRoot, normalizedPath);

            Directory.CreateDirectory(Path.GetDirectoryName(targetFileName));

            using (StreamWriter writer = new StreamWriter(targetFileName))
            {
                await writer.WriteAsync(contents);
            }
        }
        public TestRepoBuilder(string testName, RepoResources repoResources, bool deleteOnDispose = true)
        {
            RepoResources   = repoResources;
            TestName        = testName;
            DeleteOnDispose = deleteOnDispose;

            // Truncate the test name to 8 chars and compute the test repo
            const int testNameMaxLength = 8;
            string    truncatedTestName = testName.Length > testNameMaxLength?testName.Remove(testNameMaxLength) : testName;

            TestRepoRoot = TestRepoUtils.CreateUniqueTempDir(truncatedTestName);
        }
        private void CloneFileFromTestResources(string file)
        {
            string normalizedPath = TestRepoUtils.NormalizePath(file);
            string inputsFileName = GetTestInputPath(normalizedPath);
            string targetFileName = Path.Combine(TestRepoRoot, normalizedPath);

            if (!File.Exists(inputsFileName))
            {
                throw new ArgumentException($"{file} doesn't exist at {inputsFileName}");
            }

            Directory.CreateDirectory(Path.GetDirectoryName(targetFileName));
            File.Copy(inputsFileName, targetFileName);
        }
        public void Cleanup()
        {
            // Workaround to the fact that the .dotnet cannot be easily
            // placed outside the repo at the current time.
            string potentialDotNetExe = Path.Combine(TestRepoRoot, ".dotnet", TestRepoUtils.DotNetHostExecutableName);

            if (File.Exists(potentialDotNetExe))
            {
                TestRepoUtils.KillSpecificExecutable(potentialDotNetExe);
            }

            if (DeleteOnDispose)
            {
                Directory.Delete(TestRepoRoot, true);
            }
        }
        private void CloneSubdirectoryFromTestResources(string path)
        {
            string normalizedPath = TestRepoUtils.NormalizePath(path);
            string resourcesPath  = GetTestInputPath(normalizedPath);
            string testPath       = Path.Combine(TestRepoRoot, normalizedPath);

            if (!Directory.Exists(resourcesPath))
            {
                throw new ArgumentException($"{resourcesPath} is not a file or a directory that exists in the test resources");
            }

            var allFiles = Directory.GetFiles(resourcesPath, "*.*", SearchOption.AllDirectories);

            foreach (var file in allFiles)
            {
                string targetFileName = file.Replace(resourcesPath, testPath);
                Directory.CreateDirectory(Path.GetDirectoryName(targetFileName));
                File.Copy(file, targetFileName);
            }
        }
        /// <summary>
        /// Create a set of repo resources.
        /// </summary>
        /// <param name="useIsolatedRoots">
        ///     Should isolated .dotnet and .packages locations
        ///     be used? If false, then to share a dotnet root, a simple repo is created
        ///     and restored. Then the resulting .dotnet and .packages directories are
        ///     </param>
        /// <returns></returns>
        public static async Task <RepoResources> Create(bool useIsolatedRoots)
        {
            string dotnetVersion;
            string arcadeVersion;
            string dotnetRoot   = null;
            string packagesRoot = null;
            string commonRoot   = null;

            var globalJsonLocation = TestRepoBuilder.GetTestInputPath("global.json");

            using (var reader = new StreamReader(globalJsonLocation))
                using (JsonDocument doc = JsonDocument.Parse(reader.BaseStream))
                {
                    dotnetVersion = doc.RootElement.GetProperty("tools").GetProperty("dotnet").GetString();
                    arcadeVersion = doc.RootElement.GetProperty("msbuild-sdks").GetProperty("Microsoft.DotNet.Arcade.Sdk").GetString();
                }

            // If not using isolated roots, create a quick test repo builder
            // to restore things.
            if (!useIsolatedRoots)
            {
                // Common repo resources for constructing a simple repo. The
                // repo's test dir is set to not be deleted, and the .dotnet and .packages paths are extracted.
                // During the disposal of the returned set of resources, the common dir is deleted.
                var commonRepoResources = new RepoResources()
                {
                    ArcadeVersion = arcadeVersion, DotNetVersion = dotnetVersion
                };
                using (var builder = new TestRepoBuilder("common", commonRepoResources, deleteOnDispose: false))
                {
                    await builder.AddDefaultRepoSetupAsync();

                    // Create a simple project
                    builder.AddProject(ProjectCreator
                                       .Templates
                                       .SdkCsproj(
                                           targetFramework: "net5.0",
                                           outputType: "Exe"),
                                       "./src/FooPackage/FooPackage.csproj");
                    await builder.AddSimpleCSFile("./src/FooPackage/Program.cs");

                    builder.Build(
                        TestRepoUtils.BuildArg("restore"),
                        TestRepoUtils.BuildArg("ci"),
                        TestRepoUtils.BuildArg("projects"),
                        Path.Combine(builder.TestRepoRoot, "src/FooPackage/FooPackage.csproj"))();

                    commonRoot = builder.TestRepoRoot;
                    dotnetRoot = Path.Combine(builder.TestRepoRoot, ".dotnet");
                    if (!Directory.Exists(dotnetRoot))
                    {
                        // Coming from the machine
                        dotnetRoot = null;
                    }
                    packagesRoot = Path.Combine(builder.TestRepoRoot, ".packages");
                    if (!Directory.Exists(packagesRoot))
                    {
                        packagesRoot = null;
                    }
                }
            }

            RepoResources repoResources = new RepoResources()
            {
                ArcadeVersion      = arcadeVersion,
                DotNetVersion      = dotnetVersion,
                CommonPackagesRoot = packagesRoot,
                CommonDotnetRoot   = dotnetRoot,
                CommonRoot         = commonRoot
            };

            return(repoResources);
        }