Merge branch 'publish-tests1' of https://github.com/sridhar-ms/cli
This commit is contained in:
		
				commit
				
					
						f910bc9eff
					
				
			
		
					 42 changed files with 1825 additions and 128 deletions
				
			
		| 
						 | 
					@ -129,20 +129,13 @@ Download it from https://www.cmake.org
 | 
				
			||||||
    if (!$?) {
 | 
					    if (!$?) {
 | 
				
			||||||
        Write-Host "Command failed: " cmd /c "$PSScriptRoot\build\build_appdeps.cmd" "$Stage2Dir"
 | 
					        Write-Host "Command failed: " cmd /c "$PSScriptRoot\build\build_appdeps.cmd" "$Stage2Dir"
 | 
				
			||||||
        Exit 1
 | 
					        Exit 1
 | 
				
			||||||
    }
 | 
					    }    
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    # Smoke test stage2
 | 
					 | 
				
			||||||
    $env:DOTNET_HOME = "$Stage2Dir"
 | 
					    $env:DOTNET_HOME = "$Stage2Dir"
 | 
				
			||||||
    & "$PSScriptRoot\test\smoke-test.ps1"
 | 
					    # Run tests on stage2 dotnet tools
 | 
				
			||||||
 | 
					    & "$PSScriptRoot\test\runtests.ps1"
 | 
				
			||||||
    if (!$?) {
 | 
					    if (!$?) {
 | 
				
			||||||
        Write-Host "Command failed: $PSScriptRoot\test\smoke-test.ps1"
 | 
					        Write-Host "Command failed: $PSScriptRoot\test\runtests.ps1"
 | 
				
			||||||
        Exit 1
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    # E2E Test of stage2
 | 
					 | 
				
			||||||
    & "$PSScriptRoot\test\e2e-test.ps1"
 | 
					 | 
				
			||||||
    if (!$?) {
 | 
					 | 
				
			||||||
        Write-Host "Command failed: $PSScriptRoot\test\e2e-test.ps1"
 | 
					 | 
				
			||||||
        Exit 1
 | 
					        Exit 1
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -111,10 +111,6 @@ DOTNET_HOME=$STAGE2_DIR DOTNET_TOOLS=$STAGE2_DIR $REPOROOT/scripts/build/build_a
 | 
				
			||||||
COMMIT_ID=$(git rev-parse HEAD)
 | 
					COMMIT_ID=$(git rev-parse HEAD)
 | 
				
			||||||
echo $COMMIT_ID > $STAGE2_DIR/.commit
 | 
					echo $COMMIT_ID > $STAGE2_DIR/.commit
 | 
				
			||||||
 | 
					
 | 
				
			||||||
# Smoke-test the output
 | 
					 | 
				
			||||||
header "Testing stage2 ..."
 | 
					 | 
				
			||||||
DOTNET_HOME=$STAGE2_DIR DOTNET_TOOLS=$STAGE2_DIR $DIR/test/smoke-test.sh
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
# E2E test on the output
 | 
					# E2E test on the output
 | 
				
			||||||
header "Testing stage2 End to End ..."
 | 
					header "Testing stage2..."
 | 
				
			||||||
DOTNET_HOME=$STAGE2_DIR DOTNET_TOOLS=$STAGE2_DIR $DIR/test/e2e-test.sh
 | 
					DOTNET_HOME=$STAGE2_DIR DOTNET_TOOLS=$STAGE2_DIR $DIR/test/runtests.sh
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1,44 +0,0 @@
 | 
				
			||||||
#
 | 
					 | 
				
			||||||
# Copyright (c) .NET Foundation and contributors. All rights reserved.
 | 
					 | 
				
			||||||
# Licensed under the MIT license. See LICENSE file in the project root for full license information.
 | 
					 | 
				
			||||||
#
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
. "$PSScriptRoot\..\_common.ps1"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
# Restore and compile the test app
 | 
					 | 
				
			||||||
dotnet restore "$RepoRoot\test\E2E" --runtime "osx.10.10-x64" --runtime "ubuntu.14.04-x64" --runtime "win7-x64"
 | 
					 | 
				
			||||||
if (!$?) {
 | 
					 | 
				
			||||||
    Write-Host "Command failed: dotnet restore"
 | 
					 | 
				
			||||||
    Exit 1
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
dotnet publish --framework dnxcore50 --runtime "$Rid" --output "$RepoRoot\artifacts\$Rid\e2etest" "$RepoRoot\test\E2E"
 | 
					 | 
				
			||||||
if (!$?) {
 | 
					 | 
				
			||||||
    Write-Host "Command failed: dotnet publish"
 | 
					 | 
				
			||||||
    Exit 1
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
## Temporary Workaround for Native Compilation
 | 
					 | 
				
			||||||
## Need x64 Native Tools Dev Prompt Env Vars
 | 
					 | 
				
			||||||
## Tracked Here: https://github.com/dotnet/cli/issues/301
 | 
					 | 
				
			||||||
pushd "$env:VS140COMNTOOLS\..\..\VC"
 | 
					 | 
				
			||||||
cmd /c "vcvarsall.bat x64&set" |
 | 
					 | 
				
			||||||
foreach {
 | 
					 | 
				
			||||||
  if ($_ -match "=") {
 | 
					 | 
				
			||||||
    $v = $_.split("=", 2); set-item -force -literalpath "ENV:\$($v[0])" -value "$($v[1])"
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
popd
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
# Run the app and check the exit code
 | 
					 | 
				
			||||||
pushd "$RepoRoot\artifacts\$Rid\e2etest"
 | 
					 | 
				
			||||||
mv E2E.exe corehost.exe -Force
 | 
					 | 
				
			||||||
& "corehost.exe" "xunit.console.netcore.exe" "E2E.dll" -xml ..\..\e2etest.xml
 | 
					 | 
				
			||||||
if (!$?) {
 | 
					 | 
				
			||||||
    Write-Host "E2E Test Failure"
 | 
					 | 
				
			||||||
    popd
 | 
					 | 
				
			||||||
    Exit 1
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
else {
 | 
					 | 
				
			||||||
    popd
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
							
								
								
									
										68
									
								
								scripts/test/runtests.ps1
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										68
									
								
								scripts/test/runtests.ps1
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,68 @@
 | 
				
			||||||
 | 
					#
 | 
				
			||||||
 | 
					# Copyright (c) .NET Foundation and contributors. All rights reserved.
 | 
				
			||||||
 | 
					# Licensed under the MIT license. See LICENSE file in the project root for full license information.
 | 
				
			||||||
 | 
					#
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					. "$PSScriptRoot\..\_common.ps1"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					$TestBinRoot = "$RepoRoot\artifacts\tests"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					$TestProjects = @(
 | 
				
			||||||
 | 
					    "E2E",
 | 
				
			||||||
 | 
					    "Microsoft.DotNet.Tools.Publish.Tests"
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# Publish each test project
 | 
				
			||||||
 | 
					$TestProjects | ForEach-Object {
 | 
				
			||||||
 | 
					    dotnet publish --framework "dnxcore50" --runtime "$Rid" --output "$TestBinRoot" --configuration "$Configuration" "$RepoRoot\test\$_"
 | 
				
			||||||
 | 
					    if (!$?) {
 | 
				
			||||||
 | 
					        Write-Host Command failed: dotnet publish --framework "dnxcore50" --runtime "$Rid" --output "$TestBinRoot" --configuration "$Configuration" "$RepoRoot\test\$_"
 | 
				
			||||||
 | 
					        exit 1
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					## Temporary Workaround for Native Compilation
 | 
				
			||||||
 | 
					## Need x64 Native Tools Dev Prompt Env Vars
 | 
				
			||||||
 | 
					## Tracked Here: https://github.com/dotnet/cli/issues/301
 | 
				
			||||||
 | 
					pushd "$env:VS140COMNTOOLS\..\..\VC"
 | 
				
			||||||
 | 
					cmd /c "vcvarsall.bat x64&set" |
 | 
				
			||||||
 | 
					foreach {
 | 
				
			||||||
 | 
					  if ($_ -match "=") {
 | 
				
			||||||
 | 
					    $v = $_.split("=", 2); set-item -force -literalpath "ENV:\$($v[0])" -value "$($v[1])"
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					popd
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# copy TestProjects folder which is used by the test cases
 | 
				
			||||||
 | 
					mkdir -Force "$TestBinRoot\TestProjects"
 | 
				
			||||||
 | 
					cp -rec -Force "$RepoRoot\test\TestProjects\*" "$TestBinRoot\TestProjects"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					$failCount = 0
 | 
				
			||||||
 | 
					$failingTests = @()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					pushd "$TestBinRoot"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# Run each test project
 | 
				
			||||||
 | 
					$TestProjects | ForEach-Object {
 | 
				
			||||||
 | 
					    & "corerun.exe"  "xunit.console.netcore.exe" "$_.dll" -xml "$_.xml" -notrait category=failing
 | 
				
			||||||
 | 
					    $exitCode = $LastExitCode
 | 
				
			||||||
 | 
					    if ($exitCode -ne 0) {
 | 
				
			||||||
 | 
					        $failingTests += "$_"
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    $failCount += $exitCode
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					popd
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					if ($failCount -ne 0) {
 | 
				
			||||||
 | 
					    Write-Host -ForegroundColor Red "The following tests failed."
 | 
				
			||||||
 | 
					    $failingTests | ForEach-Object {
 | 
				
			||||||
 | 
					        Write-Host -ForegroundColor Red "$_.dll failed. Logs in '$TestBinRoot\$_.xml'"
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					else {
 | 
				
			||||||
 | 
					    Write-Host -ForegroundColor Green "All the tests passed!"
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Exit $failCount
 | 
				
			||||||
| 
						 | 
					@ -16,12 +16,30 @@ DIR="$( cd -P "$( dirname "$SOURCE" )" && pwd )"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
source "$DIR/../_common.sh"
 | 
					source "$DIR/../_common.sh"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
rm "$REPOROOT/test/E2E/project.lock.json"
 | 
					
 | 
				
			||||||
dotnet restore --quiet "$REPOROOT/test/E2E" --runtime "osx.10.10-x64" --runtime "ubuntu.14.04-x64" --runtime "win7-x64"
 | 
					TestBinRoot="$REPOROOT/artifacts/tests"
 | 
				
			||||||
dotnet publish --framework dnxcore50 --runtime "$RID" --output "$REPOROOT/artifacts/$RID/e2etest" "$REPOROOT/test/E2E" 
 | 
					
 | 
				
			||||||
 | 
					TestProjects=( \
 | 
				
			||||||
 | 
					    E2E \
 | 
				
			||||||
 | 
					    Microsoft.DotNet.Tools.Publish.Tests \
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					for project in ${TestProjects[@]}
 | 
				
			||||||
 | 
					do
 | 
				
			||||||
 | 
					    dotnet publish --framework "dnxcore50" --runtime "$RID" --output "$TestBinRoot" --configuration "$CONFIGURATION" "$REPOROOT/test/$project"
 | 
				
			||||||
 | 
					done
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# copy TestProjects folder which is used by the test cases
 | 
				
			||||||
 | 
					mkdir -p "$TestBinRoot/TestProjects"
 | 
				
			||||||
 | 
					cp -R $REPOROOT/test/TestProjects/* $TestBinRoot/TestProjects
 | 
				
			||||||
 | 
					
 | 
				
			||||||
# set -e will abort if the exit code of this is non-zero
 | 
					# set -e will abort if the exit code of this is non-zero
 | 
				
			||||||
pushd "$REPOROOT/artifacts/$RID/e2etest"
 | 
					pushd "$TestBinRoot"
 | 
				
			||||||
mv ./E2E ./corehost
 | 
					
 | 
				
			||||||
./corehost xunit.console.netcore.exe E2E.dll
 | 
					for project in ${TestProjects[@]}
 | 
				
			||||||
 | 
					do
 | 
				
			||||||
 | 
					    ./corerun  "xunit.console.netcore.exe" "$project.dll" -xml "project.xml"
 | 
				
			||||||
 | 
					done
 | 
				
			||||||
 | 
					
 | 
				
			||||||
popd
 | 
					popd
 | 
				
			||||||
| 
						 | 
					@ -1,25 +0,0 @@
 | 
				
			||||||
#
 | 
					 | 
				
			||||||
# Copyright (c) .NET Foundation and contributors. All rights reserved.
 | 
					 | 
				
			||||||
# Licensed under the MIT license. See LICENSE file in the project root for full license information.
 | 
					 | 
				
			||||||
#
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
. "$PSScriptRoot\..\_common.ps1"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
# Restore and compile the test app
 | 
					 | 
				
			||||||
dotnet restore "$RepoRoot\test\TestApp" --runtime "osx.10.10-x64" --runtime "ubuntu.14.04-x64" --runtime "win7-x64"
 | 
					 | 
				
			||||||
dotnet compile "$RepoRoot\test\TestApp" --output "$RepoRoot\artifacts\$Rid\smoketest"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
# Run the app and check the exit code
 | 
					 | 
				
			||||||
& "$RepoRoot\artifacts\$Rid\smoketest\TestApp.exe"
 | 
					 | 
				
			||||||
if ($LASTEXITCODE -ne 0) {
 | 
					 | 
				
			||||||
    throw "Test App failed to run"
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
# Check that a compiler error is reported
 | 
					 | 
				
			||||||
$oldErrorAction = $ErrorActionPreference
 | 
					 | 
				
			||||||
$ErrorActionPreference="SilentlyContinue"
 | 
					 | 
				
			||||||
dotnet compile "$RepoRoot\test\compile\failing\SimpleCompilerError" --framework "$Tfm" 2>$null >$null
 | 
					 | 
				
			||||||
if ($LASTEXITCODE -eq 0) {
 | 
					 | 
				
			||||||
    throw "Compiler error didn't cause non-zero exit code!"
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
$ErrorActionPreference = $oldErrorAction
 | 
					 | 
				
			||||||
| 
						 | 
					@ -1,35 +0,0 @@
 | 
				
			||||||
#!/usr/bin/env bash
 | 
					 | 
				
			||||||
#
 | 
					 | 
				
			||||||
# Copyright (c) .NET Foundation and contributors. All rights reserved.
 | 
					 | 
				
			||||||
# Licensed under the MIT license. See LICENSE file in the project root for full license information.
 | 
					 | 
				
			||||||
#
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
set -e
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
SOURCE="${BASH_SOURCE[0]}"
 | 
					 | 
				
			||||||
while [ -h "$SOURCE" ]; do # resolve $SOURCE until the file is no longer a symlink
 | 
					 | 
				
			||||||
  DIR="$( cd -P "$( dirname "$SOURCE" )" && pwd )"
 | 
					 | 
				
			||||||
  SOURCE="$(readlink "$SOURCE")"
 | 
					 | 
				
			||||||
  [[ $SOURCE != /* ]] && SOURCE="$DIR/$SOURCE" # if $SOURCE was a relative symlink, we need to resolve it relative to the path where the symlink file was located
 | 
					 | 
				
			||||||
done
 | 
					 | 
				
			||||||
DIR="$( cd -P "$( dirname "$SOURCE" )" && pwd )"
 | 
					 | 
				
			||||||
REPOROOT="$( cd -P "$DIR/../.." && pwd )"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
source "$DIR/../_common.sh"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
rm "$REPOROOT/test/TestApp/project.lock.json"
 | 
					 | 
				
			||||||
dotnet restore "$REPOROOT/test/TestApp" --runtime "osx.10.10-x64" --runtime "ubuntu.14.04-x64" --runtime "win7-x64"
 | 
					 | 
				
			||||||
dotnet compile "$REPOROOT/test/TestApp" --output "$REPOROOT/artifacts/$RID/smoketest"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
# set -e will abort if the exit code of this is non-zero
 | 
					 | 
				
			||||||
$REPOROOT/artifacts/$RID/smoketest/TestApp
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
# Check that a compiler error is reported
 | 
					 | 
				
			||||||
set +e
 | 
					 | 
				
			||||||
dotnet compile "$REPOROOT/test/compile/failing/SimpleCompilerError" --framework "$TFM" 2>/dev/null >/dev/null
 | 
					 | 
				
			||||||
rc=$?
 | 
					 | 
				
			||||||
if [ $rc == 0 ]; then
 | 
					 | 
				
			||||||
    error "Compiler failure test failed! The compiler did not fail to compile!"
 | 
					 | 
				
			||||||
    exit 1
 | 
					 | 
				
			||||||
fi
 | 
					 | 
				
			||||||
set -e
 | 
					 | 
				
			||||||
| 
						 | 
					@ -0,0 +1,176 @@
 | 
				
			||||||
 | 
					// Copyright (c) .NET Foundation and contributors. All rights reserved.
 | 
				
			||||||
 | 
					// Licensed under the MIT license. See LICENSE file in the project root for full license information.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					using System;
 | 
				
			||||||
 | 
					using System.IO;
 | 
				
			||||||
 | 
					using System.Runtime.InteropServices;
 | 
				
			||||||
 | 
					using Microsoft.DotNet.Tools.Test.Utilities;
 | 
				
			||||||
 | 
					using Xunit;
 | 
				
			||||||
 | 
					using System.Linq;
 | 
				
			||||||
 | 
					using System.Collections.Generic;
 | 
				
			||||||
 | 
					using Microsoft.DotNet.ProjectModel;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					namespace Microsoft.DotNet.Tools.Publish.Tests
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    public class PublishTests : TestBase
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        private string _testProjectsRoot = @"TestProjects";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        public static IEnumerable<object[]> PublishOptions
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            get
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                return new[]
 | 
				
			||||||
 | 
					                {
 | 
				
			||||||
 | 
					                    new object[] { "", "", "", "" },
 | 
				
			||||||
 | 
					                    new object[] { "dnxcore50", "", "", "" },
 | 
				
			||||||
 | 
					                    new object[] { "", RuntimeIdentifier.Current, "", "" },
 | 
				
			||||||
 | 
					                    new object[] { "", "", "Release", "" },
 | 
				
			||||||
 | 
					                    new object[] { "", "", "", "some/dir"},
 | 
				
			||||||
 | 
					                    //new object[] { "", "", "", "\"some/dir/with spaces\"" },
 | 
				
			||||||
 | 
					                    new object[] { "dnxcore50", RuntimeIdentifier.Current, "Debug", "some/dir" },
 | 
				
			||||||
 | 
					                };
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        [Theory]
 | 
				
			||||||
 | 
					        [MemberData("PublishOptions")]
 | 
				
			||||||
 | 
					        public void PublishOptionsTest(string framework, string runtime, string config, string outputDir)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            // create unique directories in the 'temp' folder
 | 
				
			||||||
 | 
					            var root = Temp.CreateDirectory();
 | 
				
			||||||
 | 
					            var testAppDir = root.CreateDirectory("TestApp");
 | 
				
			||||||
 | 
					            var testLibDir = root.CreateDirectory("TestLibrary");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            //copy projects to the temp dir
 | 
				
			||||||
 | 
					            CopyProjectToTempDir(Path.Combine(_testProjectsRoot, "TestApp"), testAppDir);
 | 
				
			||||||
 | 
					            CopyProjectToTempDir(Path.Combine(_testProjectsRoot, "TestLibrary"), testLibDir);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            RunRestore(testAppDir.Path);
 | 
				
			||||||
 | 
					            RunRestore(testLibDir.Path);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            // run publish
 | 
				
			||||||
 | 
					            outputDir = string.IsNullOrEmpty(outputDir) ? "" : Path.Combine(root.Path, outputDir);
 | 
				
			||||||
 | 
					            var testProject = GetProjectPath(testAppDir);
 | 
				
			||||||
 | 
					            var publishCommand = new PublishCommand(testProject, output: outputDir);
 | 
				
			||||||
 | 
					            publishCommand.Execute().Should().Pass();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            // verify the output executable generated
 | 
				
			||||||
 | 
					            var publishedDir = publishCommand.GetOutputDirectory();
 | 
				
			||||||
 | 
					            var outputExe = publishCommand.GetOutputExecutable();
 | 
				
			||||||
 | 
					            var outputPdb = Path.ChangeExtension(outputExe, "pdb");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            // lets make sure that the output exe is runnable
 | 
				
			||||||
 | 
					            var outputExePath = Path.Combine(publishedDir.FullName, publishCommand.GetOutputExecutable());
 | 
				
			||||||
 | 
					            var command = new TestCommand(outputExePath);
 | 
				
			||||||
 | 
					            command.Execute("").Should().ExitWith(100);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            // the pdb should also be published
 | 
				
			||||||
 | 
					            publishedDir.Should().HaveFile(outputPdb);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        [Fact]
 | 
				
			||||||
 | 
					        [ActiveIssue(491)]
 | 
				
			||||||
 | 
					        public void ProjectWithContentsTest()
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            // create unique directories in the 'temp' folder
 | 
				
			||||||
 | 
					            var testDir = Temp.CreateDirectory();
 | 
				
			||||||
 | 
					            var testAppDir = Path.Combine(_testProjectsRoot, "TestAppWithContents");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            // copy projects to the temp dir
 | 
				
			||||||
 | 
					            CopyProjectToTempDir(testAppDir, testDir);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            RunRestore(testDir.Path);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            // run publish
 | 
				
			||||||
 | 
					            var testProject = GetProjectPath(testDir);
 | 
				
			||||||
 | 
					            var publishCommand = new PublishCommand(testProject);
 | 
				
			||||||
 | 
					            publishCommand.Execute().Should().Pass();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            // make sure that the output dir has the content files
 | 
				
			||||||
 | 
					            publishCommand.GetOutputDirectory().Should().HaveFile("testcontentfile.txt");            
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        [Fact]
 | 
				
			||||||
 | 
					        public void BeforeRestoreTest()
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            // create unique directories in the 'temp' folder
 | 
				
			||||||
 | 
					            var root = Temp.CreateDirectory();
 | 
				
			||||||
 | 
					            var testAppDir = root.CreateDirectory("TestApp");
 | 
				
			||||||
 | 
					            var testLibDir = root.CreateDirectory("TestLibrary");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            // copy projects to the temp dir
 | 
				
			||||||
 | 
					            CopyProjectToTempDir(Path.Combine(_testProjectsRoot, "TestApp"), testAppDir);
 | 
				
			||||||
 | 
					            CopyProjectToTempDir(Path.Combine(_testProjectsRoot, "TestLibrary"), testLibDir);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            var testProject = GetProjectPath(testAppDir);
 | 
				
			||||||
 | 
					            var publishCommand = new PublishCommand(testProject);
 | 
				
			||||||
 | 
					            publishCommand.Execute().Should().Fail();
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        [Fact]
 | 
				
			||||||
 | 
					        public void LibraryPublishTest()
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            // create unique directories in the 'temp' folder
 | 
				
			||||||
 | 
					            var root = Temp.CreateDirectory();
 | 
				
			||||||
 | 
					            var testLibDir = root.CreateDirectory("TestLibrary");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            //copy projects to the temp dir            
 | 
				
			||||||
 | 
					            CopyProjectToTempDir(Path.Combine(_testProjectsRoot, "TestLibrary"), testLibDir);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            RunRestore(testLibDir.Path);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            var testProject = GetProjectPath(testLibDir);
 | 
				
			||||||
 | 
					            var publishCommand = new PublishCommand(testProject);
 | 
				
			||||||
 | 
					            publishCommand.Execute().Should().Pass();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            publishCommand.GetOutputDirectory().Should().NotHaveFile("TestLibrary.exe");
 | 
				
			||||||
 | 
					            publishCommand.GetOutputDirectory().Should().HaveFile("TestLibrary.dll");
 | 
				
			||||||
 | 
					            publishCommand.GetOutputDirectory().Should().HaveFile("TestLibrary.pdb");
 | 
				
			||||||
 | 
					            // dependencies should also be copied
 | 
				
			||||||
 | 
					            publishCommand.GetOutputDirectory().Should().HaveFile("System.Runtime.dll");
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        [Fact]
 | 
				
			||||||
 | 
					        public void CompilationFailedTest()
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            var testDir = Temp.CreateDirectory();
 | 
				
			||||||
 | 
					            var compileFailDir = Path.Combine(_testProjectsRoot, "CompileFail");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            CopyProjectToTempDir(compileFailDir, testDir);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            RunRestore(testDir.Path);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            var testProject = GetProjectPath(testDir);
 | 
				
			||||||
 | 
					            var publishCommand = new PublishCommand(testProject);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            publishCommand.Execute().Should().Fail();
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        private void CopyProjectToTempDir(string projectDir, TempDirectory tempDir)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            // copy all the files to temp dir
 | 
				
			||||||
 | 
					            foreach (var file in Directory.EnumerateFiles(projectDir))
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                // never copy project.lock.json. All the tests are expected to call 'dotnet restore'
 | 
				
			||||||
 | 
					                if (file.ToLower().EndsWith("project.lock.json"))
 | 
				
			||||||
 | 
					                {
 | 
				
			||||||
 | 
					                    continue;
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                tempDir.CopyFile(file);
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        private string GetProjectPath(TempDirectory projectDir)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            return Path.Combine(projectDir.Path, "project.json");
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        private void RunRestore(string args)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            var restoreCommand = new RestoreCommand();
 | 
				
			||||||
 | 
					            restoreCommand.Execute($"--quiet {args}").Should().Pass();
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -0,0 +1,19 @@
 | 
				
			||||||
 | 
					<?xml version="1.0" encoding="utf-8"?>
 | 
				
			||||||
 | 
					<Project ToolsVersion="14.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
 | 
				
			||||||
 | 
					  <PropertyGroup>
 | 
				
			||||||
 | 
					    <VisualStudioVersion Condition="'$(VisualStudioVersion)' == ''">14.0</VisualStudioVersion>
 | 
				
			||||||
 | 
					    <VSToolsPath Condition="'$(VSToolsPath)' == ''">$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)</VSToolsPath>
 | 
				
			||||||
 | 
					  </PropertyGroup>
 | 
				
			||||||
 | 
					  <Import Project="$(VSToolsPath)\DNX\Microsoft.DNX.Props" Condition="'$(VSToolsPath)' != ''" />
 | 
				
			||||||
 | 
					  <PropertyGroup Label="Globals">
 | 
				
			||||||
 | 
					    <ProjectGuid>386d412c-003c-47b1-8258-0e35865cb7c4</ProjectGuid>
 | 
				
			||||||
 | 
					    <RootNamespace>Microsoft.DotNet.Tools.Publish.Tests</RootNamespace>
 | 
				
			||||||
 | 
					    <BaseIntermediateOutputPath Condition="'$(BaseIntermediateOutputPath)'=='' ">..\..\artifacts\obj\$(MSBuildProjectName)</BaseIntermediateOutputPath>
 | 
				
			||||||
 | 
					    <OutputPath Condition="'$(OutputPath)'=='' ">..\..\artifacts\bin\$(MSBuildProjectName)\</OutputPath>
 | 
				
			||||||
 | 
					  </PropertyGroup>
 | 
				
			||||||
 | 
					  <PropertyGroup>
 | 
				
			||||||
 | 
					    <SchemaVersion>2.0</SchemaVersion>
 | 
				
			||||||
 | 
					  </PropertyGroup>
 | 
				
			||||||
 | 
					  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|AnyCPU'" />
 | 
				
			||||||
 | 
					  <Import Project="$(VSToolsPath)\DNX\Microsoft.DNX.targets" Condition="'$(VSToolsPath)' != ''" />
 | 
				
			||||||
 | 
					</Project>
 | 
				
			||||||
							
								
								
									
										24
									
								
								test/Microsoft.DotNet.Tools.Publish.Tests/project.json
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										24
									
								
								test/Microsoft.DotNet.Tools.Publish.Tests/project.json
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,24 @@
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					  "version": "1.0.0-*",  
 | 
				
			||||||
 | 
					  
 | 
				
			||||||
 | 
					  "dependencies": {
 | 
				
			||||||
 | 
					    "Microsoft.NETCore.Platforms": "1.0.1-*",
 | 
				
			||||||
 | 
					    "Microsoft.NETCore.Runtime": "1.0.1-*",
 | 
				
			||||||
 | 
					    "Microsoft.NETCore.TestHost" : "1.0.0-*",
 | 
				
			||||||
 | 
					    "System.Console": "4.0.0-beta-*",
 | 
				
			||||||
 | 
					    "System.Runtime": "4.0.21-beta-*",
 | 
				
			||||||
 | 
					    "System.AppContext": "4.0.1-beta-*",
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    "xunit": "2.1.0",
 | 
				
			||||||
 | 
					    "xunit.console.netcore": "1.0.2-prerelease-00101",
 | 
				
			||||||
 | 
					    "xunit.netcore.extensions": "1.0.0-prerelease-*",
 | 
				
			||||||
 | 
					    "xunit.runner.utility": "2.1.0",
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    "Microsoft.DotNet.Tools.Tests.Utilities": { "target": "project" }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  },
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    "frameworks": {
 | 
				
			||||||
 | 
					        "dnxcore50": { }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -0,0 +1,72 @@
 | 
				
			||||||
 | 
					// Copyright (c) .NET Foundation and contributors. All rights reserved.
 | 
				
			||||||
 | 
					// Licensed under the MIT license. See LICENSE file in the project root for full license information.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					using FluentAssertions;
 | 
				
			||||||
 | 
					using FluentAssertions.Execution;
 | 
				
			||||||
 | 
					using Microsoft.DotNet.Cli.Utils;
 | 
				
			||||||
 | 
					using System;
 | 
				
			||||||
 | 
					using System.Collections.Generic;
 | 
				
			||||||
 | 
					using System.Linq;
 | 
				
			||||||
 | 
					using System.Threading.Tasks;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					namespace Microsoft.DotNet.Tools.Test.Utilities
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    public class CommandResultAssertions
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        private CommandResult _commandResult;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        public CommandResultAssertions(CommandResult commandResult)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            _commandResult = commandResult;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        public AndConstraint<CommandResultAssertions> ExitWith(int expectedExitCode)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            Execute.Assertion.ForCondition(_commandResult.ExitCode == expectedExitCode)
 | 
				
			||||||
 | 
					                .FailWith("Expected command to exit with {0} but it exited with {1}.", expectedExitCode, _commandResult.ExitCode);
 | 
				
			||||||
 | 
					            return new AndConstraint<CommandResultAssertions>(this);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        public AndConstraint<CommandResultAssertions> Pass()
 | 
				
			||||||
 | 
					        {            
 | 
				
			||||||
 | 
					            Execute.Assertion.ForCondition(_commandResult.ExitCode == 0)
 | 
				
			||||||
 | 
					                .FailWith("Expected command to pass but it exited with {0}.", _commandResult.ExitCode);
 | 
				
			||||||
 | 
					            return new AndConstraint<CommandResultAssertions>(this);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        public AndConstraint<CommandResultAssertions> Fail()
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            Execute.Assertion.ForCondition(_commandResult.ExitCode != 0)
 | 
				
			||||||
 | 
					                .FailWith("Expected command to fail but it exited with {0}.", _commandResult.ExitCode);
 | 
				
			||||||
 | 
					            return new AndConstraint<CommandResultAssertions>(this);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        public AndConstraint<CommandResultAssertions> HaveStdOut()
 | 
				
			||||||
 | 
					        {            
 | 
				
			||||||
 | 
					            Execute.Assertion.ForCondition(!string.IsNullOrEmpty(_commandResult.StdOut))
 | 
				
			||||||
 | 
					                .FailWith("Command did not output anything to stdout");
 | 
				
			||||||
 | 
					            return new AndConstraint<CommandResultAssertions>(this);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        public AndConstraint<CommandResultAssertions> HaveStdErr()
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            Execute.Assertion.ForCondition(!string.IsNullOrEmpty(_commandResult.StdErr))
 | 
				
			||||||
 | 
					                .FailWith("Command did not output anything to stderr");
 | 
				
			||||||
 | 
					            return new AndConstraint<CommandResultAssertions>(this);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        public AndConstraint<CommandResultAssertions> NotHaveStdOut()
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            Execute.Assertion.ForCondition(string.IsNullOrEmpty(_commandResult.StdOut))
 | 
				
			||||||
 | 
					                .FailWith("Expected command to not output to stdout but found - {0}{1}", Environment.NewLine, _commandResult.StdOut);
 | 
				
			||||||
 | 
					            return new AndConstraint<CommandResultAssertions>(this);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        public AndConstraint<CommandResultAssertions> NotHaveStdErr()
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            Execute.Assertion.ForCondition(string.IsNullOrEmpty(_commandResult.StdErr))
 | 
				
			||||||
 | 
					                .FailWith("Expected command to not output to stderr but found - {0}{1}", Environment.NewLine, _commandResult.StdErr);
 | 
				
			||||||
 | 
					            return new AndConstraint<CommandResultAssertions>(this);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -0,0 +1,20 @@
 | 
				
			||||||
 | 
					// Copyright (c) .NET Foundation and contributors. All rights reserved.
 | 
				
			||||||
 | 
					// Licensed under the MIT license. See LICENSE file in the project root for full license information.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					using Microsoft.DotNet.Cli.Utils;
 | 
				
			||||||
 | 
					using System;
 | 
				
			||||||
 | 
					using System.Collections.Generic;
 | 
				
			||||||
 | 
					using System.Linq;
 | 
				
			||||||
 | 
					using System.Threading.Tasks;
 | 
				
			||||||
 | 
					using FluentAssertions;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					namespace Microsoft.DotNet.Tools.Test.Utilities
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    public static class CommandResultExtensions
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        public static CommandResultAssertions Should(this CommandResult commandResult)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            return new CommandResultAssertions(commandResult);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -0,0 +1,67 @@
 | 
				
			||||||
 | 
					// Copyright (c) .NET Foundation and contributors. All rights reserved.
 | 
				
			||||||
 | 
					// Licensed under the MIT license. See LICENSE file in the project root for full license information.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					using FluentAssertions;
 | 
				
			||||||
 | 
					using FluentAssertions.Execution;
 | 
				
			||||||
 | 
					using Microsoft.DotNet.Cli.Utils;
 | 
				
			||||||
 | 
					using System;
 | 
				
			||||||
 | 
					using System.Collections.Generic;
 | 
				
			||||||
 | 
					using System.IO;
 | 
				
			||||||
 | 
					using System.Linq;
 | 
				
			||||||
 | 
					using System.Threading.Tasks;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					namespace Microsoft.DotNet.Tools.Test.Utilities
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    public class DirectoryInfoAssertions
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        private DirectoryInfo _dirInfo;        
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        public DirectoryInfoAssertions(DirectoryInfo dir)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            _dirInfo = dir;                        
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        public AndConstraint<DirectoryInfoAssertions> Exist()
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            _dirInfo.Exists.Should().BeTrue();
 | 
				
			||||||
 | 
					            Execute.Assertion.ForCondition(_dirInfo.Exists)
 | 
				
			||||||
 | 
					                .FailWith("Expected directory {0} does not exist.", _dirInfo.FullName);
 | 
				
			||||||
 | 
					            return new AndConstraint<DirectoryInfoAssertions>(this);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        public AndConstraint<DirectoryInfoAssertions> HaveFile(string expectedFile)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            var file = _dirInfo.EnumerateFiles(expectedFile, SearchOption.TopDirectoryOnly).SingleOrDefault();
 | 
				
			||||||
 | 
					            Execute.Assertion.ForCondition(file != null)
 | 
				
			||||||
 | 
					                .FailWith("Expected File {0} cannot be found in directory {1}.", expectedFile, _dirInfo.FullName);
 | 
				
			||||||
 | 
					            return new AndConstraint<DirectoryInfoAssertions>(this);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        public AndConstraint<DirectoryInfoAssertions> NotHaveFile(string expectedFile)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            var file = _dirInfo.EnumerateFiles(expectedFile, SearchOption.TopDirectoryOnly).SingleOrDefault();
 | 
				
			||||||
 | 
					            Execute.Assertion.ForCondition(file == null)
 | 
				
			||||||
 | 
					                .FailWith("File {0} should not be found in directory {1}.", expectedFile, _dirInfo.FullName);
 | 
				
			||||||
 | 
					            return new AndConstraint<DirectoryInfoAssertions>(this);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        public AndConstraint<DirectoryInfoAssertions> HaveFiles(IEnumerable<string> expectedFiles)
 | 
				
			||||||
 | 
					        {            
 | 
				
			||||||
 | 
					            foreach (var expectedFile in expectedFiles)
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                HaveFile(expectedFile);
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            return new AndConstraint<DirectoryInfoAssertions>(this);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        public AndConstraint<DirectoryInfoAssertions> HaveDirectory(string expectedDir)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            var dir = _dirInfo.EnumerateDirectories(expectedDir, SearchOption.TopDirectoryOnly).SingleOrDefault();
 | 
				
			||||||
 | 
					            Execute.Assertion.ForCondition(dir != null)
 | 
				
			||||||
 | 
					                .FailWith("Expected directory {0} cannot be found inside directory {1}.", expectedDir, _dirInfo.FullName);
 | 
				
			||||||
 | 
					            
 | 
				
			||||||
 | 
					            return new AndConstraint<DirectoryInfoAssertions>(new DirectoryInfoAssertions(dir));
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -0,0 +1,19 @@
 | 
				
			||||||
 | 
					// Copyright (c) .NET Foundation and contributors. All rights reserved.
 | 
				
			||||||
 | 
					// Licensed under the MIT license. See LICENSE file in the project root for full license information.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					using System;
 | 
				
			||||||
 | 
					using System.Collections.Generic;
 | 
				
			||||||
 | 
					using System.IO;
 | 
				
			||||||
 | 
					using System.Linq;
 | 
				
			||||||
 | 
					using System.Threading.Tasks;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					namespace Microsoft.DotNet.Tools.Test.Utilities
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    public static class DirectoryInfoExtensions
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        public static DirectoryInfoAssertions Should(this DirectoryInfo dir)
 | 
				
			||||||
 | 
					        {            
 | 
				
			||||||
 | 
					            return new DirectoryInfoAssertions(dir);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -0,0 +1,107 @@
 | 
				
			||||||
 | 
					// Copyright (c) .NET Foundation and contributors. All rights reserved.
 | 
				
			||||||
 | 
					// Licensed under the MIT license. See LICENSE file in the project root for full license information.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					using System;
 | 
				
			||||||
 | 
					using System.Collections.Generic;
 | 
				
			||||||
 | 
					using System.IO;
 | 
				
			||||||
 | 
					using System.Linq;
 | 
				
			||||||
 | 
					using System.Runtime.InteropServices;
 | 
				
			||||||
 | 
					using System.Threading.Tasks;
 | 
				
			||||||
 | 
					using Microsoft.DotNet.Cli.Utils;
 | 
				
			||||||
 | 
					using Microsoft.DotNet.ProjectModel;
 | 
				
			||||||
 | 
					using Microsoft.DotNet.Tools.Test.Utilities;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					namespace Microsoft.DotNet.Tools.Publish.Tests
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    public sealed class PublishCommand : TestCommand
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        private Project _project;
 | 
				
			||||||
 | 
					        private string _path;
 | 
				
			||||||
 | 
					        private string _framework;
 | 
				
			||||||
 | 
					        private string _runtime;
 | 
				
			||||||
 | 
					        private string _config;
 | 
				
			||||||
 | 
					        private string _output;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        public PublishCommand(string projectPath, string framework="", string runtime="", string output="", string config="")
 | 
				
			||||||
 | 
					            : base("dotnet")
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            _path = projectPath;
 | 
				
			||||||
 | 
					            _project = ProjectReader.GetProject(projectPath);
 | 
				
			||||||
 | 
					            _framework = framework;
 | 
				
			||||||
 | 
					            _runtime = runtime;
 | 
				
			||||||
 | 
					            _output = output;
 | 
				
			||||||
 | 
					            _config = config;            
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        public override CommandResult Execute(string args="")
 | 
				
			||||||
 | 
					        {            
 | 
				
			||||||
 | 
					            args = $"publish {BuildArgs()} {args}";
 | 
				
			||||||
 | 
					            return base.Execute(args);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        public string ProjectName
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            get
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                return _project.Name;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        private string BuildRelativeOutputPath()
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            // lets try to build an approximate output path            
 | 
				
			||||||
 | 
					            string config = string.IsNullOrEmpty(_config) ? "Debug" : _config;
 | 
				
			||||||
 | 
					            string framework = string.IsNullOrEmpty(_framework) ? 
 | 
				
			||||||
 | 
					                _project.GetTargetFrameworks().First().FrameworkName.GetShortFolderName() : _framework;
 | 
				
			||||||
 | 
					            string runtime = string.IsNullOrEmpty(_runtime) ? RuntimeIdentifier.Current : _runtime;
 | 
				
			||||||
 | 
					            string output = Path.Combine("bin", config, framework, runtime);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            return output;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        public DirectoryInfo GetOutputDirectory()
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            if (!string.IsNullOrEmpty(_output))
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                return new DirectoryInfo(_output);
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            string output = Path.Combine(_project.ProjectDirectory, BuildRelativeOutputPath());
 | 
				
			||||||
 | 
					            return new DirectoryInfo(output);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        public string GetOutputExecutable()
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            var result = _project.Name;
 | 
				
			||||||
 | 
					            result += RuntimeInformation.IsOSPlatform(OSPlatform.Windows) ? ".exe" : "";
 | 
				
			||||||
 | 
					            return result;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        private string BuildArgs()
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            return $"{_path} {GetFrameworkOption()} {GetRuntimeOption()} {GetOutputOption()} {GetConfigOption()}";
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        private string GetFrameworkOption()
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            return string.IsNullOrEmpty(_framework) ? "" : $"-f {_framework}";
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        private string GetRuntimeOption()
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            return string.IsNullOrEmpty(_runtime) ? "" : $"-r {_runtime}";
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        private string GetOutputOption()
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            return string.IsNullOrEmpty(_output) ? "" : $"-o {_output}";
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        private string GetConfigOption()
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            return string.IsNullOrEmpty(_config) ? "" : $"-c {_output}";
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -0,0 +1,23 @@
 | 
				
			||||||
 | 
					// Copyright (c) .NET Foundation and contributors. All rights reserved.
 | 
				
			||||||
 | 
					// Licensed under the MIT license. See LICENSE file in the project root for full license information.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					using Microsoft.DotNet.Cli.Utils;
 | 
				
			||||||
 | 
					using Microsoft.DotNet.Tools.Test.Utilities;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					namespace Microsoft.DotNet.Tools.Publish.Tests
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    public sealed class RestoreCommand : TestCommand
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        public RestoreCommand()
 | 
				
			||||||
 | 
					            : base("dotnet")
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        public override CommandResult Execute(string args="")
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            args = $"restore {args}";
 | 
				
			||||||
 | 
					            return base.Execute(args);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -0,0 +1,30 @@
 | 
				
			||||||
 | 
					// Copyright (c) .NET Foundation and contributors. All rights reserved.
 | 
				
			||||||
 | 
					// Licensed under the MIT license. See LICENSE file in the project root for full license information.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					using Microsoft.DotNet.Cli.Utils;
 | 
				
			||||||
 | 
					using System;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					namespace Microsoft.DotNet.Tools.Test.Utilities
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    public class TestCommand
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        protected string _command;
 | 
				
			||||||
 | 
					        
 | 
				
			||||||
 | 
					        public TestCommand(string command)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            _command = command;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        public virtual CommandResult Execute(string args)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            Console.WriteLine($"Executing - {_command} {args}");
 | 
				
			||||||
 | 
					            var commandResult = Command.Create(_command, args)
 | 
				
			||||||
 | 
					                .ForwardStdErr()
 | 
				
			||||||
 | 
					                .ForwardStdOut()
 | 
				
			||||||
 | 
					                .Execute();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            return commandResult;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -0,0 +1,20 @@
 | 
				
			||||||
 | 
					<?xml version="1.0" encoding="utf-8"?>
 | 
				
			||||||
 | 
					<Project ToolsVersion="14.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
 | 
				
			||||||
 | 
					  <PropertyGroup>
 | 
				
			||||||
 | 
					    <VisualStudioVersion Condition="'$(VisualStudioVersion)' == ''">14.0</VisualStudioVersion>
 | 
				
			||||||
 | 
					    <VSToolsPath Condition="'$(VSToolsPath)' == ''">$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)</VSToolsPath>
 | 
				
			||||||
 | 
					  </PropertyGroup>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  <Import Project="$(VSToolsPath)\DNX\Microsoft.DNX.Props" Condition="'$(VSToolsPath)' != ''" />
 | 
				
			||||||
 | 
					  <PropertyGroup Label="Globals">
 | 
				
			||||||
 | 
					    <ProjectGuid>e4f46eab-b5a5-4e60-9b9d-40a1fadbf45c</ProjectGuid>
 | 
				
			||||||
 | 
					    <RootNamespace>Microsoft.DotNet.Tools.Test.Utilities</RootNamespace>
 | 
				
			||||||
 | 
					    <BaseIntermediateOutputPath Condition="'$(BaseIntermediateOutputPath)'=='' ">..\..\artifacts\obj\$(MSBuildProjectName)</BaseIntermediateOutputPath>
 | 
				
			||||||
 | 
					    <OutputPath Condition="'$(OutputPath)'=='' ">..\..\artifacts\bin\$(MSBuildProjectName)\</OutputPath>
 | 
				
			||||||
 | 
					  </PropertyGroup>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  <PropertyGroup>
 | 
				
			||||||
 | 
					    <SchemaVersion>2.0</SchemaVersion>
 | 
				
			||||||
 | 
					  </PropertyGroup>
 | 
				
			||||||
 | 
					  <Import Project="$(VSToolsPath)\DNX\Microsoft.DNX.targets" Condition="'$(VSToolsPath)' != ''" />
 | 
				
			||||||
 | 
					</Project>
 | 
				
			||||||
| 
						 | 
					@ -0,0 +1,30 @@
 | 
				
			||||||
 | 
					// Copyright (c) .NET Foundation and contributors. All rights reserved.
 | 
				
			||||||
 | 
					// Licensed under the MIT license. See LICENSE file in the project root for full license information.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					using System;
 | 
				
			||||||
 | 
					using System.IO;
 | 
				
			||||||
 | 
					 
 | 
				
			||||||
 | 
					namespace Microsoft.DotNet.Tools.Test.Utilities
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    public sealed class DisposableDirectory : TempDirectory, IDisposable
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        public DisposableDirectory(TempRoot root)
 | 
				
			||||||
 | 
					            : base(root)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					 
 | 
				
			||||||
 | 
					        public void Dispose()
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            if (Path != null && Directory.Exists(Path))
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                try
 | 
				
			||||||
 | 
					                {
 | 
				
			||||||
 | 
					                    Directory.Delete(Path, recursive: true);
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					                catch
 | 
				
			||||||
 | 
					                {
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -0,0 +1,83 @@
 | 
				
			||||||
 | 
					// Copyright (c) .NET Foundation and contributors. All rights reserved.
 | 
				
			||||||
 | 
					// Licensed under the MIT license. See LICENSE file in the project root for full license information.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					using System;
 | 
				
			||||||
 | 
					using System.IO;
 | 
				
			||||||
 | 
					using System.Runtime.InteropServices;
 | 
				
			||||||
 | 
					using Microsoft.Win32.SafeHandles;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					namespace Microsoft.DotNet.Tools.Test.Utilities
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    public sealed class DisposableFile : TempFile, IDisposable
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        public DisposableFile(string path)
 | 
				
			||||||
 | 
					            : base(path)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        public DisposableFile(string prefix = null, string extension = null, string directory = null, string callerSourcePath = null, int callerLineNumber = 0)
 | 
				
			||||||
 | 
					            : base(prefix, extension, directory, callerSourcePath, callerLineNumber)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        public void Dispose()
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            if (Path != null && File.Exists(Path))
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                try
 | 
				
			||||||
 | 
					                {
 | 
				
			||||||
 | 
					                    File.Delete(Path);
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					                catch (UnauthorizedAccessException)
 | 
				
			||||||
 | 
					                {
 | 
				
			||||||
 | 
					                    try
 | 
				
			||||||
 | 
					                    {
 | 
				
			||||||
 | 
					                        // the file might still be memory-mapped, delete on close:
 | 
				
			||||||
 | 
					                        DeleteFileOnClose(Path);
 | 
				
			||||||
 | 
					                    }
 | 
				
			||||||
 | 
					                    catch (IOException ex)
 | 
				
			||||||
 | 
					                    {
 | 
				
			||||||
 | 
					                        throw new InvalidOperationException(string.Format(@"
 | 
				
			||||||
 | 
					The file '{0}' seems to have been opened in a way that prevents us from deleting it on close.
 | 
				
			||||||
 | 
					Is the file loaded as an assembly (e.g. via Assembly.LoadFile)?
 | 
				
			||||||
 | 
					 
 | 
				
			||||||
 | 
					{1}: {2}", Path, ex.GetType().Name, ex.Message), ex);
 | 
				
			||||||
 | 
					                    }
 | 
				
			||||||
 | 
					                    catch (UnauthorizedAccessException)
 | 
				
			||||||
 | 
					                    {
 | 
				
			||||||
 | 
					                        //  We should ignore this exception if we got it the second time, 
 | 
				
			||||||
 | 
					                        //  the most important reason is that the file has already been 
 | 
				
			||||||
 | 
					                        //  scheduled for deletion and will be deleted when all handles 
 | 
				
			||||||
 | 
					                        //  are closed.
 | 
				
			||||||
 | 
					                    }
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        [DllImport("kernel32.dll", PreserveSig = false)]
 | 
				
			||||||
 | 
					        private static extern void SetFileInformationByHandle(SafeFileHandle handle, int fileInformationClass, ref uint fileDispositionInfoDeleteFile, int bufferSize);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        private const int FileDispositionInfo = 4;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        internal static void PrepareDeleteOnCloseStreamForDisposal(FileStream stream)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            // tomat: Set disposition to "delete" on the stream, so to avoid ForeFront EndPoint
 | 
				
			||||||
 | 
					            // Protection driver scanning the file. Note that after calling this on a file that's open with DeleteOnClose, 
 | 
				
			||||||
 | 
					            // the file can't be opened again, not even by the same process.
 | 
				
			||||||
 | 
					            uint trueValue = 1;
 | 
				
			||||||
 | 
					            SetFileInformationByHandle(stream.SafeFileHandle, FileDispositionInfo, ref trueValue, sizeof(uint));
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        /// <summary>
 | 
				
			||||||
 | 
					        /// Marks given file for automatic deletion when all its handles are closed.
 | 
				
			||||||
 | 
					        /// Note that after doing this the file can't be opened again, not even by the same process.
 | 
				
			||||||
 | 
					        /// </summary>
 | 
				
			||||||
 | 
					        internal static void DeleteFileOnClose(string fullPath)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            using (var stream = new FileStream(fullPath, FileMode.Open, FileAccess.ReadWrite, FileShare.Delete | FileShare.ReadWrite, 8, FileOptions.DeleteOnClose))
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                PrepareDeleteOnCloseStreamForDisposal(stream);
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -0,0 +1,183 @@
 | 
				
			||||||
 | 
					// Copyright (c) .NET Foundation and contributors. All rights reserved.
 | 
				
			||||||
 | 
					// Licensed under the MIT license. See LICENSE file in the project root for full license information.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					namespace Microsoft.DotNet.Tools.Test.Utilities
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    /// <summary>
 | 
				
			||||||
 | 
					    /// Implements a few file name utilities that are needed by the compiler.
 | 
				
			||||||
 | 
					    /// In general the compiler is not supposed to understand the format of the paths.
 | 
				
			||||||
 | 
					    /// In rare cases it needs to check if a string is a valid file name or change the extension 
 | 
				
			||||||
 | 
					    /// (embedded resources, netmodules, output name).
 | 
				
			||||||
 | 
					    /// The APIs are intentionally limited to cover just these rare cases. Do not add more APIs.
 | 
				
			||||||
 | 
					    /// </summary>
 | 
				
			||||||
 | 
					    internal static class FileNameUtilities
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        private const string DirectorySeparatorStr = "\\";
 | 
				
			||||||
 | 
					        internal const char DirectorySeparatorChar = '\\';
 | 
				
			||||||
 | 
					        internal const char AltDirectorySeparatorChar = '/';
 | 
				
			||||||
 | 
					        internal const char VolumeSeparatorChar = ':';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        /// <summary>
 | 
				
			||||||
 | 
					        /// Returns true if the string represents an unqualified file name. 
 | 
				
			||||||
 | 
					        /// The name may contain any characters but directory and volume separators.
 | 
				
			||||||
 | 
					        /// </summary>
 | 
				
			||||||
 | 
					        /// <param name="path">Path.</param>
 | 
				
			||||||
 | 
					        /// <returns>
 | 
				
			||||||
 | 
					        /// True if <paramref name="path"/> is a simple file name, false if it is null or includes a directory specification.
 | 
				
			||||||
 | 
					        /// </returns>
 | 
				
			||||||
 | 
					        internal static bool IsFileName(string path)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            return IndexOfFileName(path) == 0;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        /// <summary>
 | 
				
			||||||
 | 
					        /// Returns the offset in <paramref name="path"/> where the dot that starts an extension is, or -1 if the path doesn't have an extension.
 | 
				
			||||||
 | 
					        /// </summary>
 | 
				
			||||||
 | 
					        /// <remarks>
 | 
				
			||||||
 | 
					        /// Returns 0 for path ".foo".
 | 
				
			||||||
 | 
					        /// Returns -1 for path "foo.".
 | 
				
			||||||
 | 
					        /// </remarks>
 | 
				
			||||||
 | 
					        private static int IndexOfExtension(string path)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            if (path == null)
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                return -1;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            int length = path.Length;
 | 
				
			||||||
 | 
					            int i = length;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            while (--i >= 0)
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                char c = path[i];
 | 
				
			||||||
 | 
					                if (c == '.')
 | 
				
			||||||
 | 
					                {
 | 
				
			||||||
 | 
					                    if (i != length - 1)
 | 
				
			||||||
 | 
					                    {
 | 
				
			||||||
 | 
					                        return i;
 | 
				
			||||||
 | 
					                    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                    return -1;
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                if (c == DirectorySeparatorChar || c == AltDirectorySeparatorChar || c == VolumeSeparatorChar)
 | 
				
			||||||
 | 
					                {
 | 
				
			||||||
 | 
					                    break;
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            return -1;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        /// <summary>
 | 
				
			||||||
 | 
					        /// Returns an extension of the specified path string.
 | 
				
			||||||
 | 
					        /// </summary>
 | 
				
			||||||
 | 
					        /// <remarks>
 | 
				
			||||||
 | 
					        /// The same functionality as <see cref="System.IO.Path.GetExtension(string)"/> but doesn't throw an exception
 | 
				
			||||||
 | 
					        /// if there are invalid characters in the path.
 | 
				
			||||||
 | 
					        /// </remarks>
 | 
				
			||||||
 | 
					        internal static string GetExtension(string path)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            if (path == null)
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                return null;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            int index = IndexOfExtension(path);
 | 
				
			||||||
 | 
					            return (index >= 0) ? path.Substring(index) : string.Empty;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        /// <summary>
 | 
				
			||||||
 | 
					        /// Removes extension from path.
 | 
				
			||||||
 | 
					        /// </summary>
 | 
				
			||||||
 | 
					        /// <remarks>
 | 
				
			||||||
 | 
					        /// Returns "foo" for path "foo.".
 | 
				
			||||||
 | 
					        /// Returns "foo.." for path "foo...".
 | 
				
			||||||
 | 
					        /// </remarks>
 | 
				
			||||||
 | 
					        private static string RemoveExtension(string path)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            if (path == null)
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                return null;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            int index = IndexOfExtension(path);
 | 
				
			||||||
 | 
					            if (index >= 0)
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                return path.Substring(0, index);
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            // trim last ".", if present
 | 
				
			||||||
 | 
					            if (path.Length > 0 && path[path.Length - 1] == '.')
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                return path.Substring(0, path.Length - 1);
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            return path;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        /// <summary>
 | 
				
			||||||
 | 
					        /// Returns path with the extension changed to <paramref name="extension"/>.
 | 
				
			||||||
 | 
					        /// </summary>
 | 
				
			||||||
 | 
					        /// <returns>
 | 
				
			||||||
 | 
					        /// Equivalent of <see cref="System.IO.Path.ChangeExtension(string, string)"/>
 | 
				
			||||||
 | 
					        /// 
 | 
				
			||||||
 | 
					        /// If <paramref name="path"/> is null, returns null. 
 | 
				
			||||||
 | 
					        /// If path does not end with an extension, the new extension is appended to the path.
 | 
				
			||||||
 | 
					        /// If extension is null, equivalent to <see cref="RemoveExtension"/>.
 | 
				
			||||||
 | 
					        /// </returns>
 | 
				
			||||||
 | 
					        internal static string ChangeExtension(string path, string extension)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            if (path == null)
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                return null;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            var pathWithoutExtension = RemoveExtension(path);
 | 
				
			||||||
 | 
					            if (extension == null || path.Length == 0)
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                return pathWithoutExtension;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            if (extension.Length == 0 || extension[0] != '.')
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                return pathWithoutExtension + "." + extension;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            return pathWithoutExtension + extension;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        /// <summary>
 | 
				
			||||||
 | 
					        /// Returns the position in given path where the file name starts.
 | 
				
			||||||
 | 
					        /// </summary>
 | 
				
			||||||
 | 
					        /// <returns>-1 if path is null.</returns>
 | 
				
			||||||
 | 
					        internal static int IndexOfFileName(string path)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            if (path == null)
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                return -1;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            for (int i = path.Length - 1; i >= 0; i--)
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                char ch = path[i];
 | 
				
			||||||
 | 
					                if (ch == DirectorySeparatorChar || ch == AltDirectorySeparatorChar || ch == VolumeSeparatorChar)
 | 
				
			||||||
 | 
					                {
 | 
				
			||||||
 | 
					                    return i + 1;
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            return 0;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        /// <summary>
 | 
				
			||||||
 | 
					        /// Get file name from path.
 | 
				
			||||||
 | 
					        /// </summary>
 | 
				
			||||||
 | 
					        /// <remarks>Unlike <see cref="System.IO.Path.GetFileName"/> doesn't check for invalid path characters.</remarks>
 | 
				
			||||||
 | 
					        internal static string GetFileName(string path)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            int fileNameStart = IndexOfFileName(path);
 | 
				
			||||||
 | 
					            return (fileNameStart <= 0) ? path : path.Substring(fileNameStart);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -0,0 +1,43 @@
 | 
				
			||||||
 | 
					// Copyright (c) .NET Foundation and contributors. All rights reserved.
 | 
				
			||||||
 | 
					// Licensed under the MIT license. See LICENSE file in the project root for full license information.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					using System;
 | 
				
			||||||
 | 
					using System.Collections.Generic;
 | 
				
			||||||
 | 
					using System.Collections.Immutable;
 | 
				
			||||||
 | 
					using System.Diagnostics;
 | 
				
			||||||
 | 
					using System.IO;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					namespace Microsoft.DotNet.Tools.Test.Utilities
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    /// <summary>
 | 
				
			||||||
 | 
					    /// The collection of extension methods for the <see cref="ImmutableArray{T}"/> type
 | 
				
			||||||
 | 
					    /// </summary>
 | 
				
			||||||
 | 
					    public static class ImmutableArrayTestExtensions
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        /// <summary>
 | 
				
			||||||
 | 
					        /// Writes read-only array of bytes to the specified file.
 | 
				
			||||||
 | 
					        /// </summary>
 | 
				
			||||||
 | 
					        /// <param name="bytes">Data to write to the file.</param>
 | 
				
			||||||
 | 
					        /// <param name="path">File path.</param>
 | 
				
			||||||
 | 
					        internal static void WriteToFile(this ImmutableArray<byte> bytes, string path)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            Debug.Assert(!bytes.IsDefault);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            const int bufferSize = 4096;
 | 
				
			||||||
 | 
					            using (FileStream fileStream = new FileStream(path, FileMode.Create, FileAccess.Write, FileShare.Read, bufferSize))
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                // PERF: Consider using an ObjectPool<byte[]> here
 | 
				
			||||||
 | 
					                byte[] buffer = new byte[Math.Min(bufferSize, bytes.Length)];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                int offset = 0;
 | 
				
			||||||
 | 
					                while (offset < bytes.Length)
 | 
				
			||||||
 | 
					                {
 | 
				
			||||||
 | 
					                    int length = Math.Min(bufferSize, bytes.Length - offset);
 | 
				
			||||||
 | 
					                    bytes.CopyTo(offset, buffer, 0, length);
 | 
				
			||||||
 | 
					                    fileStream.Write(buffer, 0, length);
 | 
				
			||||||
 | 
					                    offset += length;
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -0,0 +1,43 @@
 | 
				
			||||||
 | 
					// Copyright (c) .NET Foundation and contributors. All rights reserved.
 | 
				
			||||||
 | 
					// Licensed under the MIT license. See LICENSE file in the project root for full license information.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					namespace Microsoft.DotNet.Tools.Test.Utilities
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    internal enum PathKind
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        /// <summary>
 | 
				
			||||||
 | 
					        /// Null or empty.
 | 
				
			||||||
 | 
					        /// </summary>
 | 
				
			||||||
 | 
					        Empty,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        /// <summary>
 | 
				
			||||||
 | 
					        /// "file"
 | 
				
			||||||
 | 
					        /// </summary>
 | 
				
			||||||
 | 
					        Relative,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        /// <summary>
 | 
				
			||||||
 | 
					        /// ".\file"
 | 
				
			||||||
 | 
					        /// </summary>
 | 
				
			||||||
 | 
					        RelativeToCurrentDirectory,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        /// <summary>
 | 
				
			||||||
 | 
					        /// "..\file"
 | 
				
			||||||
 | 
					        /// </summary>
 | 
				
			||||||
 | 
					        RelativeToCurrentParent,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        /// <summary>
 | 
				
			||||||
 | 
					        /// "\dir\file"
 | 
				
			||||||
 | 
					        /// </summary>
 | 
				
			||||||
 | 
					        RelativeToCurrentRoot,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        /// <summary>
 | 
				
			||||||
 | 
					        /// "C:dir\file"
 | 
				
			||||||
 | 
					        /// </summary>
 | 
				
			||||||
 | 
					        RelativeToDriveDirectory,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        /// <summary>
 | 
				
			||||||
 | 
					        /// "C:\file" or "\\machine" (UNC).
 | 
				
			||||||
 | 
					        /// </summary>
 | 
				
			||||||
 | 
					        Absolute,
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -0,0 +1,379 @@
 | 
				
			||||||
 | 
					// Copyright (c) .NET Foundation and contributors. All rights reserved.
 | 
				
			||||||
 | 
					// Licensed under the MIT license. See LICENSE file in the project root for full license information.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					using System;
 | 
				
			||||||
 | 
					using System.Diagnostics;
 | 
				
			||||||
 | 
					using System.IO;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					namespace Microsoft.DotNet.Tools.Test.Utilities
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    // Contains path parsing utilities.
 | 
				
			||||||
 | 
					    // We need our own because System.IO.Path is insufficient for our purposes
 | 
				
			||||||
 | 
					    // For example we need to be able to work with invalid paths or paths containing wildcards
 | 
				
			||||||
 | 
					    internal static class PathUtilities
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        // We consider '/' a directory separator on Unix like systems. 
 | 
				
			||||||
 | 
					        // On Windows both / and \ are equally accepted.
 | 
				
			||||||
 | 
					        internal static readonly char DirectorySeparatorChar = IsUnixLikePlatform ? '/' : '\\';
 | 
				
			||||||
 | 
					        internal static readonly char AltDirectorySeparatorChar = '/';
 | 
				
			||||||
 | 
					        internal static readonly string DirectorySeparatorStr = new string(DirectorySeparatorChar, 1);
 | 
				
			||||||
 | 
					        internal const char VolumeSeparatorChar = ':';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        private static bool IsUnixLikePlatform
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            get
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                return Path.DirectorySeparatorChar == '/';
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        internal static bool IsDirectorySeparator(char c)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            return c == DirectorySeparatorChar || c == AltDirectorySeparatorChar;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        internal static string TrimTrailingSeparators(string s)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            int lastSeparator = s.Length;
 | 
				
			||||||
 | 
					            while (lastSeparator > 0 && IsDirectorySeparator(s[lastSeparator - 1]))
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                lastSeparator = lastSeparator - 1;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            if (lastSeparator != s.Length)
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                s = s.Substring(0, lastSeparator);
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            return s;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        internal static string GetExtension(string path)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            return FileNameUtilities.GetExtension(path);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        internal static string ChangeExtension(string path, string extension)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            return FileNameUtilities.ChangeExtension(path, extension);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        internal static string RemoveExtension(string path)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            return FileNameUtilities.ChangeExtension(path, extension: null);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        internal static string GetFileName(string path)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            return FileNameUtilities.GetFileName(path);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        /// <summary>
 | 
				
			||||||
 | 
					        /// Get directory name from path.
 | 
				
			||||||
 | 
					        /// </summary>
 | 
				
			||||||
 | 
					        /// <remarks>
 | 
				
			||||||
 | 
					        /// Unlike <see cref="System.IO.Path.GetDirectoryName"/> it
 | 
				
			||||||
 | 
					        ///     doesn't check for invalid path characters, 
 | 
				
			||||||
 | 
					        ///     doesn't strip any trailing directory separators (TODO: tomat),
 | 
				
			||||||
 | 
					        ///     doesn't recognize UNC structure \\computer-name\share\directory-name\file-name (TODO: tomat).
 | 
				
			||||||
 | 
					        /// </remarks>
 | 
				
			||||||
 | 
					        /// <returns>Prefix of path that represents a directory. </returns>
 | 
				
			||||||
 | 
					        internal static string GetDirectoryName(string path)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            int fileNameStart = FileNameUtilities.IndexOfFileName(path);
 | 
				
			||||||
 | 
					            if (fileNameStart < 0)
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                return null;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            return path.Substring(0, fileNameStart);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        internal static PathKind GetPathKind(string path)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            if (string.IsNullOrWhiteSpace(path))
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                return PathKind.Empty;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            // "C:\"
 | 
				
			||||||
 | 
					            // "\\machine" (UNC)
 | 
				
			||||||
 | 
					            // "/etc"      (Unix)
 | 
				
			||||||
 | 
					            if (IsAbsolute(path))
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                return PathKind.Absolute;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            // "."
 | 
				
			||||||
 | 
					            // ".."
 | 
				
			||||||
 | 
					            // ".\"
 | 
				
			||||||
 | 
					            // "..\"
 | 
				
			||||||
 | 
					            if (path.Length > 0 && path[0] == '.')
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                if (path.Length == 1 || IsDirectorySeparator(path[1]))
 | 
				
			||||||
 | 
					                {
 | 
				
			||||||
 | 
					                    return PathKind.RelativeToCurrentDirectory;
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                if (path[1] == '.')
 | 
				
			||||||
 | 
					                {
 | 
				
			||||||
 | 
					                    if (path.Length == 2 || IsDirectorySeparator(path[2]))
 | 
				
			||||||
 | 
					                    {
 | 
				
			||||||
 | 
					                        return PathKind.RelativeToCurrentParent;
 | 
				
			||||||
 | 
					                    }
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            if (!IsUnixLikePlatform)
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                // "\"
 | 
				
			||||||
 | 
					                // "\foo"
 | 
				
			||||||
 | 
					                if (path.Length >= 1 && IsDirectorySeparator(path[0]))
 | 
				
			||||||
 | 
					                {
 | 
				
			||||||
 | 
					                    return PathKind.RelativeToCurrentRoot;
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                // "C:foo"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                if (path.Length >= 2 && path[1] == VolumeSeparatorChar && (path.Length <= 2 || !IsDirectorySeparator(path[2])))
 | 
				
			||||||
 | 
					                {
 | 
				
			||||||
 | 
					                    return PathKind.RelativeToDriveDirectory;
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            // "foo.dll"
 | 
				
			||||||
 | 
					            return PathKind.Relative;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        internal static bool IsAbsolute(string path)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            if (string.IsNullOrEmpty(path))
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                return false;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            if (IsUnixLikePlatform)
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                return path[0] == DirectorySeparatorChar;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            // "C:\"
 | 
				
			||||||
 | 
					            if (IsDriveRootedAbsolutePath(path))
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                // Including invalid paths (e.g. "*:\")
 | 
				
			||||||
 | 
					                return true;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            // "\\machine\share"
 | 
				
			||||||
 | 
					            // Including invalid/incomplete UNC paths (e.g. "\\foo")
 | 
				
			||||||
 | 
					            return path.Length >= 2 &&
 | 
				
			||||||
 | 
					                IsDirectorySeparator(path[0]) &&
 | 
				
			||||||
 | 
					                IsDirectorySeparator(path[1]);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        /// <summary>
 | 
				
			||||||
 | 
					        /// Returns true if given path is absolute and starts with a drive specification ("C:\").
 | 
				
			||||||
 | 
					        /// </summary>
 | 
				
			||||||
 | 
					        private static bool IsDriveRootedAbsolutePath(string path)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            Debug.Assert(!IsUnixLikePlatform);
 | 
				
			||||||
 | 
					            return path.Length >= 3 && path[1] == VolumeSeparatorChar && IsDirectorySeparator(path[2]);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        /// <summary>
 | 
				
			||||||
 | 
					        /// Get a prefix of given path which is the root of the path.
 | 
				
			||||||
 | 
					        /// </summary>
 | 
				
			||||||
 | 
					        /// <returns>
 | 
				
			||||||
 | 
					        /// Root of an absolute path or null if the path isn't absolute or has invalid format (e.g. "\\").
 | 
				
			||||||
 | 
					        /// It may or may not end with a directory separator (e.g. "C:\", "C:\foo", "\\machine\share", etc.) .
 | 
				
			||||||
 | 
					        /// </returns>
 | 
				
			||||||
 | 
					        internal static string GetPathRoot(string path)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            if (string.IsNullOrWhiteSpace(path))
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                return null;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            int length = GetPathRootLength(path);
 | 
				
			||||||
 | 
					            return (length != -1) ? path.Substring(0, length) : null;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        private static int GetPathRootLength(string path)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            Debug.Assert(!string.IsNullOrEmpty(path));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            if (IsUnixLikePlatform)
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                if (IsDirectorySeparator(path[0]))
 | 
				
			||||||
 | 
					                {
 | 
				
			||||||
 | 
					                    //  "/*"
 | 
				
			||||||
 | 
					                    return 1;
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            else
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                // "C:\"
 | 
				
			||||||
 | 
					                if (IsDriveRootedAbsolutePath(path))
 | 
				
			||||||
 | 
					                {
 | 
				
			||||||
 | 
					                    return 3;
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                if (IsDirectorySeparator(path[0]))
 | 
				
			||||||
 | 
					                {
 | 
				
			||||||
 | 
					                    // "\\machine\share"
 | 
				
			||||||
 | 
					                    return GetUncPathRootLength(path);
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            return -1;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        /// <summary>
 | 
				
			||||||
 | 
					        /// Calculates the length of root of an UNC path.
 | 
				
			||||||
 | 
					        /// </summary>
 | 
				
			||||||
 | 
					        /// <remarks>
 | 
				
			||||||
 | 
					        /// "\\server\share" is root of UNC path "\\server\share\dir1\dir2\file".
 | 
				
			||||||
 | 
					        /// </remarks>
 | 
				
			||||||
 | 
					        private static int GetUncPathRootLength(string path)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            Debug.Assert(IsDirectorySeparator(path[0]));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            // root:
 | 
				
			||||||
 | 
					            // [directory-separator]{2,}[^directory-separator]+[directory-separator]+[^directory-separator]+
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            int serverIndex = IndexOfNonDirectorySeparator(path, 1);
 | 
				
			||||||
 | 
					            if (serverIndex < 2)
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                return -1;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            int separator = IndexOfDirectorySeparator(path, serverIndex);
 | 
				
			||||||
 | 
					            if (separator == -1)
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                return -1;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            int shareIndex = IndexOfNonDirectorySeparator(path, separator);
 | 
				
			||||||
 | 
					            if (shareIndex == -1)
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                return -1;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            int rootEnd = IndexOfDirectorySeparator(path, shareIndex);
 | 
				
			||||||
 | 
					            return rootEnd == -1 ? path.Length : rootEnd;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        private static int IndexOfDirectorySeparator(string path, int start)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            for (int i = start; i < path.Length; i++)
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                if (IsDirectorySeparator(path[i]))
 | 
				
			||||||
 | 
					                {
 | 
				
			||||||
 | 
					                    return i;
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            return -1;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        private static int IndexOfNonDirectorySeparator(string path, int start)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            for (int i = start; i < path.Length; i++)
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                if (!IsDirectorySeparator(path[i]))
 | 
				
			||||||
 | 
					                {
 | 
				
			||||||
 | 
					                    return i;
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            return -1;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        /// <summary>
 | 
				
			||||||
 | 
					        /// Combines an absolute path with a relative.
 | 
				
			||||||
 | 
					        /// </summary>
 | 
				
			||||||
 | 
					        /// <param name="root">Absolute root path.</param>
 | 
				
			||||||
 | 
					        /// <param name="relativePath">Relative path.</param>
 | 
				
			||||||
 | 
					        /// <returns>
 | 
				
			||||||
 | 
					        /// An absolute combined path, or null if <paramref name="relativePath"/> is 
 | 
				
			||||||
 | 
					        /// absolute (e.g. "C:\abc", "\\machine\share\abc"), 
 | 
				
			||||||
 | 
					        /// relative to the current root (e.g. "\abc"), 
 | 
				
			||||||
 | 
					        /// or relative to a drive directory (e.g. "C:abc\def").
 | 
				
			||||||
 | 
					        /// </returns>
 | 
				
			||||||
 | 
					        /// <seealso cref="CombinePossiblyRelativeAndRelativePaths"/>
 | 
				
			||||||
 | 
					        internal static string CombineAbsoluteAndRelativePaths(string root, string relativePath)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            Debug.Assert(IsAbsolute(root));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            return CombinePossiblyRelativeAndRelativePaths(root, relativePath);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        /// <summary>
 | 
				
			||||||
 | 
					        /// Combine two paths, the first of which may be absolute.
 | 
				
			||||||
 | 
					        /// </summary>
 | 
				
			||||||
 | 
					        /// <param name="rootOpt">First path: absolute, relative, or null.</param>
 | 
				
			||||||
 | 
					        /// <param name="relativePath">Second path: relative and non-null.</param>
 | 
				
			||||||
 | 
					        /// <returns>null, if <paramref name="rootOpt"/> is null; a combined path, otherwise.</returns>
 | 
				
			||||||
 | 
					        /// <seealso cref="CombineAbsoluteAndRelativePaths"/>
 | 
				
			||||||
 | 
					        internal static string CombinePossiblyRelativeAndRelativePaths(string rootOpt, string relativePath)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            if (string.IsNullOrEmpty(rootOpt))
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                return null;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            switch (GetPathKind(relativePath))
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                case PathKind.Empty:
 | 
				
			||||||
 | 
					                    return rootOpt;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                case PathKind.Absolute:
 | 
				
			||||||
 | 
					                case PathKind.RelativeToCurrentRoot:
 | 
				
			||||||
 | 
					                case PathKind.RelativeToDriveDirectory:
 | 
				
			||||||
 | 
					                    return null;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            return CombinePathsUnchecked(rootOpt, relativePath);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        internal static string CombinePathsUnchecked(string root, string relativePath)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            Debug.Assert(!string.IsNullOrEmpty(root));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            char c = root[root.Length - 1];
 | 
				
			||||||
 | 
					            if (!IsDirectorySeparator(c) && c != VolumeSeparatorChar)
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                return root + DirectorySeparatorStr + relativePath;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            return root + relativePath;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        internal static string RemoveTrailingDirectorySeparator(string path)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            if (path.Length > 0 && IsDirectorySeparator(path[path.Length - 1]))
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                return path.Substring(0, path.Length - 1);
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            else
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                return path;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        /// <summary>
 | 
				
			||||||
 | 
					        /// Determines whether an assembly reference is considered an assembly file path or an assembly name.
 | 
				
			||||||
 | 
					        /// used, for example, on values of /r and #r.
 | 
				
			||||||
 | 
					        /// </summary>
 | 
				
			||||||
 | 
					        internal static bool IsFilePath(string assemblyDisplayNameOrPath)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            Debug.Assert(assemblyDisplayNameOrPath != null);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            string extension = FileNameUtilities.GetExtension(assemblyDisplayNameOrPath);
 | 
				
			||||||
 | 
					            return string.Equals(extension, ".dll", StringComparison.OrdinalIgnoreCase)
 | 
				
			||||||
 | 
					                || string.Equals(extension, ".exe", StringComparison.OrdinalIgnoreCase)
 | 
				
			||||||
 | 
					                || assemblyDisplayNameOrPath.IndexOf(DirectorySeparatorChar) != -1
 | 
				
			||||||
 | 
					                || assemblyDisplayNameOrPath.IndexOf(AltDirectorySeparatorChar) != -1;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -0,0 +1,94 @@
 | 
				
			||||||
 | 
					// Copyright (c) .NET Foundation and contributors. All rights reserved.
 | 
				
			||||||
 | 
					// Licensed under the MIT license. See LICENSE file in the project root for full license information.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					using System;
 | 
				
			||||||
 | 
					using System.Diagnostics;
 | 
				
			||||||
 | 
					using System.IO;
 | 
				
			||||||
 | 
					 
 | 
				
			||||||
 | 
					namespace Microsoft.DotNet.Tools.Test.Utilities
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    public class TempDirectory
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        private readonly string _path;
 | 
				
			||||||
 | 
					        private readonly TempRoot _root;
 | 
				
			||||||
 | 
					 
 | 
				
			||||||
 | 
					        protected TempDirectory(TempRoot root)
 | 
				
			||||||
 | 
					            : this(CreateUniqueDirectory(TempRoot.Root), root)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					 
 | 
				
			||||||
 | 
					        private TempDirectory(string path, TempRoot root)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            Debug.Assert(path != null);
 | 
				
			||||||
 | 
					            Debug.Assert(root != null);
 | 
				
			||||||
 | 
					 
 | 
				
			||||||
 | 
					            _path = path;
 | 
				
			||||||
 | 
					            _root = root;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					 
 | 
				
			||||||
 | 
					        private static string CreateUniqueDirectory(string basePath)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            while (true)
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                string dir = System.IO.Path.Combine(basePath, Guid.NewGuid().ToString());
 | 
				
			||||||
 | 
					                try
 | 
				
			||||||
 | 
					                {
 | 
				
			||||||
 | 
					                    Directory.CreateDirectory(dir);
 | 
				
			||||||
 | 
					                    return dir;
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					                catch (IOException)
 | 
				
			||||||
 | 
					                {
 | 
				
			||||||
 | 
					                    // retry
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					 
 | 
				
			||||||
 | 
					        public string Path
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            get { return _path; }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					 
 | 
				
			||||||
 | 
					        /// <summary>
 | 
				
			||||||
 | 
					        /// Creates a file in this directory.
 | 
				
			||||||
 | 
					        /// </summary>
 | 
				
			||||||
 | 
					        /// <param name="name">File name.</param>
 | 
				
			||||||
 | 
					        public TempFile CreateFile(string name)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            string filePath = System.IO.Path.Combine(_path, name);
 | 
				
			||||||
 | 
					            TempRoot.CreateStream(filePath);
 | 
				
			||||||
 | 
					            return _root.AddFile(new DisposableFile(filePath));
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					 
 | 
				
			||||||
 | 
					        /// <summary>
 | 
				
			||||||
 | 
					        /// Creates a file in this directory that is a copy of the specified file.
 | 
				
			||||||
 | 
					        /// </summary>
 | 
				
			||||||
 | 
					        public TempFile CopyFile(string originalPath)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            string name = System.IO.Path.GetFileName(originalPath);
 | 
				
			||||||
 | 
					            string filePath = System.IO.Path.Combine(_path, name);
 | 
				
			||||||
 | 
					            File.Copy(originalPath, filePath);
 | 
				
			||||||
 | 
					            return _root.AddFile(new DisposableFile(filePath));
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					 
 | 
				
			||||||
 | 
					        /// <summary>
 | 
				
			||||||
 | 
					        /// Creates a subdirectory in this directory.
 | 
				
			||||||
 | 
					        /// </summary>
 | 
				
			||||||
 | 
					        /// <param name="name">Directory name or unrooted directory path.</param>
 | 
				
			||||||
 | 
					        public TempDirectory CreateDirectory(string name)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            string dirPath = System.IO.Path.Combine(_path, name);
 | 
				
			||||||
 | 
					            Directory.CreateDirectory(dirPath);
 | 
				
			||||||
 | 
					            return new TempDirectory(dirPath, _root);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        public void SetCurrentDirectory()
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            Directory.SetCurrentDirectory(_path);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					 
 | 
				
			||||||
 | 
					        public override string ToString()
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            return _path;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -0,0 +1,118 @@
 | 
				
			||||||
 | 
					// Copyright (c) .NET Foundation and contributors. All rights reserved.
 | 
				
			||||||
 | 
					// Licensed under the MIT license. See LICENSE file in the project root for full license information.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					using System;
 | 
				
			||||||
 | 
					using System.Collections.Immutable;
 | 
				
			||||||
 | 
					using System.IO;
 | 
				
			||||||
 | 
					using System.Text;
 | 
				
			||||||
 | 
					using System.Diagnostics;
 | 
				
			||||||
 | 
					using System.Threading.Tasks;
 | 
				
			||||||
 | 
					 
 | 
				
			||||||
 | 
					namespace Microsoft.DotNet.Tools.Test.Utilities
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    public class TempFile
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        private readonly string _path;
 | 
				
			||||||
 | 
					 
 | 
				
			||||||
 | 
					        internal TempFile(string path)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            Debug.Assert(PathUtilities.IsAbsolute(path));
 | 
				
			||||||
 | 
					            _path = path;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					 
 | 
				
			||||||
 | 
					        internal TempFile(string prefix, string extension, string directory, string callerSourcePath, int callerLineNumber)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            while (true)
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                if (prefix == null)
 | 
				
			||||||
 | 
					                {
 | 
				
			||||||
 | 
					                    prefix = System.IO.Path.GetFileName(callerSourcePath) + "_" + callerLineNumber.ToString() + "_";
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					 
 | 
				
			||||||
 | 
					                _path = System.IO.Path.Combine(directory ?? TempRoot.Root, prefix + Guid.NewGuid() + (extension ?? ".tmp"));
 | 
				
			||||||
 | 
					 
 | 
				
			||||||
 | 
					                try
 | 
				
			||||||
 | 
					                {
 | 
				
			||||||
 | 
					                    TempRoot.CreateStream(_path);
 | 
				
			||||||
 | 
					                    break;
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					                catch (PathTooLongException)
 | 
				
			||||||
 | 
					                {
 | 
				
			||||||
 | 
					                    throw;
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					                catch (DirectoryNotFoundException)
 | 
				
			||||||
 | 
					                {
 | 
				
			||||||
 | 
					                    throw;
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					                catch (IOException)
 | 
				
			||||||
 | 
					                {
 | 
				
			||||||
 | 
					                    // retry
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					 
 | 
				
			||||||
 | 
					        public FileStream Open(FileAccess access = FileAccess.ReadWrite)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            return new FileStream(_path, FileMode.Open, access);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					 
 | 
				
			||||||
 | 
					        public string Path
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            get { return _path; }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					 
 | 
				
			||||||
 | 
					        public TempFile WriteAllText(string content, Encoding encoding)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            File.WriteAllText(_path, content, encoding);
 | 
				
			||||||
 | 
					            return this;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					 
 | 
				
			||||||
 | 
					        public TempFile WriteAllText(string content)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            File.WriteAllText(_path, content);
 | 
				
			||||||
 | 
					            return this;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					 
 | 
				
			||||||
 | 
					        public async Task<TempFile> WriteAllTextAsync(string content, Encoding encoding)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            using (var sw = new StreamWriter(File.Create(_path), encoding))
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                await sw.WriteAsync(content).ConfigureAwait(false);
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					 
 | 
				
			||||||
 | 
					            return this;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					 
 | 
				
			||||||
 | 
					        public Task<TempFile> WriteAllTextAsync(string content)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            return WriteAllTextAsync(content, Encoding.UTF8);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					 
 | 
				
			||||||
 | 
					        public TempFile WriteAllBytes(byte[] content)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            File.WriteAllBytes(_path, content);
 | 
				
			||||||
 | 
					            return this;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					 
 | 
				
			||||||
 | 
					        public TempFile WriteAllBytes(ImmutableArray<byte> content)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            content.WriteToFile(_path);
 | 
				
			||||||
 | 
					            return this;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					 
 | 
				
			||||||
 | 
					        public string ReadAllText()
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            return File.ReadAllText(_path);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					 
 | 
				
			||||||
 | 
					        public TempFile CopyContentFrom(string path)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            return WriteAllBytes(File.ReadAllBytes(path));
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					 
 | 
				
			||||||
 | 
					        public override string ToString()
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            return _path;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -0,0 +1,72 @@
 | 
				
			||||||
 | 
					// Copyright (c) .NET Foundation and contributors. All rights reserved.
 | 
				
			||||||
 | 
					// Licensed under the MIT license. See LICENSE file in the project root for full license information.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					using System;
 | 
				
			||||||
 | 
					using System.Collections.Generic;
 | 
				
			||||||
 | 
					using System.IO;
 | 
				
			||||||
 | 
					using System.Runtime.CompilerServices;
 | 
				
			||||||
 | 
					 
 | 
				
			||||||
 | 
					namespace Microsoft.DotNet.Tools.Test.Utilities
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    public sealed class TempRoot : IDisposable
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        private readonly List<IDisposable> _temps = new List<IDisposable>();
 | 
				
			||||||
 | 
					        public static readonly string Root;
 | 
				
			||||||
 | 
					 
 | 
				
			||||||
 | 
					        static TempRoot()
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            Root = Path.Combine(Path.GetTempPath(), "DotnetCLITests");
 | 
				
			||||||
 | 
					            Directory.CreateDirectory(Root);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					 
 | 
				
			||||||
 | 
					        public void Dispose()
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            if (_temps != null)
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                DisposeAll(_temps);
 | 
				
			||||||
 | 
					                _temps.Clear();
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					 
 | 
				
			||||||
 | 
					        private static void DisposeAll(IEnumerable<IDisposable> temps)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            foreach (var temp in temps)
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                try
 | 
				
			||||||
 | 
					                {
 | 
				
			||||||
 | 
					                    if (temp != null)
 | 
				
			||||||
 | 
					                    {
 | 
				
			||||||
 | 
					                        temp.Dispose();
 | 
				
			||||||
 | 
					                    }
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					                catch
 | 
				
			||||||
 | 
					                {
 | 
				
			||||||
 | 
					                    // ignore
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					 
 | 
				
			||||||
 | 
					        public TempDirectory CreateDirectory()
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            var dir = new DisposableDirectory(this);
 | 
				
			||||||
 | 
					            _temps.Add(dir);
 | 
				
			||||||
 | 
					            return dir;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					 
 | 
				
			||||||
 | 
					        public TempFile CreateFile(string prefix = null, string extension = null, string directory = null, [CallerFilePath]string callerSourcePath = null, [CallerLineNumber]int callerLineNumber = 0)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            return AddFile(new DisposableFile(prefix, extension, directory, callerSourcePath, callerLineNumber));
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					 
 | 
				
			||||||
 | 
					        public DisposableFile AddFile(DisposableFile file)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            _temps.Add(file);
 | 
				
			||||||
 | 
					            return file;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					 
 | 
				
			||||||
 | 
					        internal static void CreateStream(string fullPath)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            using (var file = new FileStream(fullPath, FileMode.CreateNew)) { }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										49
									
								
								test/Microsoft.DotNet.Tools.Tests.Utilities/TestBase.cs
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										49
									
								
								test/Microsoft.DotNet.Tools.Tests.Utilities/TestBase.cs
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,49 @@
 | 
				
			||||||
 | 
					// Copyright (c) .NET Foundation and contributors. All rights reserved.
 | 
				
			||||||
 | 
					// Licensed under the MIT license. See LICENSE file in the project root for full license information.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					using System;
 | 
				
			||||||
 | 
					using System.Collections.Generic;
 | 
				
			||||||
 | 
					using System.Linq;
 | 
				
			||||||
 | 
					using System.Threading.Tasks;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					namespace Microsoft.DotNet.Tools.Test.Utilities
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    /// <summary>
 | 
				
			||||||
 | 
					    /// Base class for all unit test classes.
 | 
				
			||||||
 | 
					    /// </summary>
 | 
				
			||||||
 | 
					    public abstract class TestBase : IDisposable
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        private TempRoot _temp;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        protected TestBase()
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        public static string GetUniqueName()
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            return Guid.NewGuid().ToString("D");
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        public TempRoot Temp
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            get
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                if (_temp == null)
 | 
				
			||||||
 | 
					                {
 | 
				
			||||||
 | 
					                    _temp = new TempRoot();
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                return _temp;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        public virtual void Dispose()
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            if (_temp != null)
 | 
				
			||||||
 | 
					            {                
 | 
				
			||||||
 | 
					                _temp.Dispose();
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										22
									
								
								test/Microsoft.DotNet.Tools.Tests.Utilities/project.json
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										22
									
								
								test/Microsoft.DotNet.Tools.Tests.Utilities/project.json
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,22 @@
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					  "version": "1.0.0-*",
 | 
				
			||||||
 | 
					  "description": "Microsoft.DotNet.Tools.Tests.Utilities Class Library",
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  "dependencies": {
 | 
				
			||||||
 | 
					    "System.Collections": "4.0.11-*",
 | 
				
			||||||
 | 
					    "System.Collections.Immutable": "1.1.38-*",
 | 
				
			||||||
 | 
					    "System.Linq": "4.0.1-*",
 | 
				
			||||||
 | 
					    "System.Threading": "4.0.11-*",
 | 
				
			||||||
 | 
					    "System.IO.FileSystem": "4.0.1-*",
 | 
				
			||||||
 | 
					    "System.IO": "4.0.11-*",
 | 
				
			||||||
 | 
					    "System.Runtime.InteropServices": "4.0.21-*",
 | 
				
			||||||
 | 
					    "FluentAssertions": "4.0.0",
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    "Microsoft.DotNet.Cli.Utils": { "target": "project" }
 | 
				
			||||||
 | 
					  }, 
 | 
				
			||||||
 | 
					  
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  "frameworks": {
 | 
				
			||||||
 | 
					    "dnxcore50": { }
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -8,9 +8,10 @@ namespace TestApp
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    public class Program
 | 
					    public class Program
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        public static void Main(string[] args)
 | 
					        public static int Main(string[] args)
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            Console.WriteLine(TestLibrary.Helper.GetMessage());
 | 
					            Console.WriteLine(TestLibrary.Helper.GetMessage());
 | 
				
			||||||
 | 
					            return 100;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
							
								
								
									
										13
									
								
								test/TestProjects/TestAppWithContents/Program.cs
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										13
									
								
								test/TestProjects/TestAppWithContents/Program.cs
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,13 @@
 | 
				
			||||||
 | 
					using System;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					namespace ConsoleApplication
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    public class Program
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        public static int Main(string[] args)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            Console.WriteLine("Hello World!");
 | 
				
			||||||
 | 
					            return 100;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										18
									
								
								test/TestProjects/TestAppWithContents/project.json
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										18
									
								
								test/TestProjects/TestAppWithContents/project.json
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,18 @@
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					  "version": "1.0.0-*",
 | 
				
			||||||
 | 
					  "compilationOptions": {
 | 
				
			||||||
 | 
					    "emitEntryPoint": true
 | 
				
			||||||
 | 
					  },
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  "dependencies": {
 | 
				
			||||||
 | 
					    "Microsoft.NETCore.Runtime": "1.0.1-beta-*",
 | 
				
			||||||
 | 
					    "System.IO": "4.0.10-beta-*",
 | 
				
			||||||
 | 
					    "System.Console": "4.0.0-beta-*",
 | 
				
			||||||
 | 
					    "System.Runtime": "4.0.21-beta-*"
 | 
				
			||||||
 | 
					  }, 
 | 
				
			||||||
 | 
					  
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    "frameworks": {
 | 
				
			||||||
 | 
					        "dnxcore50": { }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -0,0 +1 @@
 | 
				
			||||||
 | 
					This is to test if contents are copied correctly by the dotnet tools
 | 
				
			||||||
		Reference in a new issue