Make build/boilerplate files consistent with other ASP.NET repos

This commit is contained in:
Steve Sanderson 2017-08-29 13:07:01 +01:00
parent 2b117da4ab
commit 175457a03a
19 changed files with 461 additions and 664 deletions

18
.appveyor.yml Normal file
View File

@ -0,0 +1,18 @@
init:
- git config --global core.autocrlf true
branches:
only:
- master
- release
- dev
- /^(.*\/)?ci-.*$/
build_script:
- ps: .\build.ps1
clone_depth: 1
environment:
global:
DOTNET_SKIP_FIRST_TIME_EXPERIENCE: true
DOTNET_CLI_TELEMETRY_OPTOUT: 1
test: off
deploy: off
os: Visual Studio 2017

52
.gitignore vendored
View File

@ -1,12 +1,42 @@
**/intermediate/**
**/artifacts/**
packages/**
.nuget/**
.build/**
**/.vs/**
*.user
[Oo]bj/
[Bb]in/
TestResults/
.nuget/
*.sln.ide/
_ReSharper.*/
packages/
artifacts/
PublishProfiles/
.vs/
bower_components/
node_modules/
**/wwwroot/lib/
debugSettings.json
project.lock.json
Templates.BranchSettings.targets
**/.vscode
test/**/bin/**
test/**/obj/**
*.user
*.suo
*.cache
*.docstates
_ReSharper.*
nuget.exe
*net45.csproj
*net451.csproj
*k10.csproj
*.psess
*.vsp
*.pidb
*.userprefs
*DS_Store
*.ncrunchsolution
*.*sdf
*.ipch
.settings
*.sln.ide
node_modules
**/[Cc]ompiler/[Rr]esources/**/*.js
*launchSettings.json
.build/
.testPublish/
.vscode
global.json
korebuild-lock.txt

View File

@ -1,10 +0,0 @@
language: csharp
sudo: false
branches:
only:
- master
- release
- dev
- /^(.*\/)?ci-.*$/
script:
- ./build.sh --quiet verify

View File

@ -1,22 +1,4 @@
Contributing
======
General Information on contributing is in the [Contributing Guide](https://github.com/aspnet/Home/blob/dev/CONTRIBUTING.md) in the Home repo.
Specific guidelines for this repo are as follows:
# Contributing to an existing template
## Updating preexisting content
If you are simply editing a preexisting file, you can make the code change and submit a pull request.
## Adding or removing a file
**When updating a base template, the following also needs to be updated:**
* *.vstemplate located at src\BaseTemplates folder for the template being updated.
**When updating a template rule, the following also needs to be updated:**
* Templates.xml located at src\Templates.xml: Update the appropriate AddFile or ReplaceFile rule as needed.
* TemplateRules.csproj: Update the appropriate LooseFiles element as needed.
# Contributing a new template
Please open an issue for new template requests.
Information on contributing to this repo is in the [Contributing Guide](https://github.com/aspnet/Home/blob/dev/CONTRIBUTING.md) in the Home repo.

View File

@ -1,12 +1,14 @@
Copyright (c) .NET Foundation. All rights reserved.
Copyright (c) .NET Foundation and Contributors
All rights reserved.
Licensed under the Apache License, Version 2.0 (the "License"); you may not use
these files except in compliance with the License. You may obtain a copy of the
this file except in compliance with the License. You may obtain a copy of the
License at
http://www.apache.org/licenses/LICENSE-2.0
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software distributed
under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
CONDITIONS OF ANY KIND, either express or implied. See the License for the
specific language governing permissions and limitations under the License.
specific language governing permissions and limitations under the License.

9
NuGet.config Normal file
View File

@ -0,0 +1,9 @@
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<packageSources>
<clear />
<add key="AspNetCore" value="https://dotnet.myget.org/F/aspnetcore-ci-dev/api/v3/index.json" />
<add key="AspNetCoreTools" value="https://dotnet.myget.org/F/aspnetcore-tools/api/v3/index.json" />
<add key="NuGet" value="https://api.nuget.org/v3/index.json" />
</packageSources>
</configuration>

View File

@ -1,6 +1,7 @@
#Templates
# Templates
## Getting Started
ASP.NET Templates provide project templates which are used in Visual Studio for creating ASP.NET Core applications.
ASP.NET Templates provide project templates which are used in .NET Core for creating ASP.NET Core applications.
This project is part of ASP.NET Core. You can find samples, documentation and getting started instructions for ASP.NET Core at the [Home](https://github.com/aspnet/home) repo.

View File

@ -1,11 +0,0 @@
<Project ToolsVersion="15.0">
<PropertyGroup>
<IntermediateFolder>$(MSBuildThisFileDirectory)obj\</IntermediateFolder>
<ArtifactsFolder>$(MSBuildThisFileDirectory)artifacts\</ArtifactsFolder>
<TemplatesFolder>$(ArtifactsFolder)templates\</TemplatesFolder>
<TemplatesNoTimestampFolder>$(ArtifactsFolder)templates-notimestamp\</TemplatesNoTimestampFolder>
<TestFolder>$(ArtifactsFolder)test\</TestFolder>
<BuildToolsFolder>$(MSBuildThisFileDirectory).tools\</BuildToolsFolder>
<NuGet>&quot;$(BuildToolsFolder)nuget.exe&quot;</NuGet>
</PropertyGroup>
</Project>

View File

@ -1,31 +0,0 @@
<Project ToolsVersion="15.0">
<Import Project="Templates.settings.targets" />
<PropertyGroup Condition=" '$(PackageVersion)' == '' ">
<PackageReleaseVersion>1.0.0</PackageReleaseVersion>
<PackageBuildQuality>$(BUILD_QUALITY)</PackageBuildQuality>
<PackageBuildQuality Condition=" '$(PackageBuildQuality)' == '' ">beta1</PackageBuildQuality>
<PackageVersion>$(PackageReleaseVersion)-$(PackageBuildQuality)</PackageVersion>
<BUILD_NUMBER Condition="'$(BUILD_NUMBER)' == ''">0</BUILD_NUMBER>
<AssemblyReleaseVersion>$(PackageReleaseVersion).$(BUILD_NUMBER)</AssemblyReleaseVersion>
<PackageVersion Condition="'$(NO_TIMESTAMP)' != 'true'">$(PackageVersion)-$([System.DateTime]::Now.ToString("yyyyMMdd"))-$(BUILD_NUMBER)</PackageVersion>
</PropertyGroup>
<PropertyGroup>
<Authors>Microsoft</Authors>
<ProjectUrl>https://github.com/aspnet/templates</ProjectUrl>
<LicenseUrl>https://www.microsoft.com/web/webpi/eula/net_library_eula_enu.htm</LicenseUrl>
<ImageUrl>http://go.microsoft.com/fwlink/?LinkID=288859</ImageUrl>
<Tags>template</Tags>
<Company>Microsoft</Company>
<Copyright>Copyright © Microsoft Corporation</Copyright>
<GenerateAssemblyInfo Condition="'$(BuildingInsideVisualStudio)' != ''">False</GenerateAssemblyInfo>
<GenerateAssemblyFileVersionAttribute>False</GenerateAssemblyFileVersionAttribute>
<GenerateAssemblyVersionAttribute>False</GenerateAssemblyVersionAttribute>
<GenerateAssemblyInformationalVersionAttribute>False</GenerateAssemblyInformationalVersionAttribute>
</PropertyGroup>
<PropertyGroup>
<AssemblyOriginatorKeyFile>$(MSBuildThisFileDirectory)Key.snk</AssemblyOriginatorKeyFile>
<SignAssembly>true</SignAssembly>
<PublicSign Condition=" '$(OS)' != 'Windows_NT' ">true</PublicSign>
</PropertyGroup>
</Project>

View File

@ -1,13 +0,0 @@
init:
- git config --global core.autocrlf true
branches:
only:
- master
- release
- dev
- /^(.*\/)?ci-.*$/
build_script:
- build.cmd --quiet verify
clone_depth: 1
test: off
deploy: off

View File

@ -1,4 +1,2 @@
@ECHO OFF
PowerShell -NoProfile -NoLogo -ExecutionPolicy unrestricted -Command "[System.Threading.Thread]::CurrentThread.CurrentCulture = ''; [System.Threading.Thread]::CurrentThread.CurrentUICulture = '';& '%~dp0dotnet-install.ps1' %*; exit $LASTEXITCODE"
tools\build.cmd
PowerShell -NoProfile -NoLogo -ExecutionPolicy unrestricted -Command "[System.Threading.Thread]::CurrentThread.CurrentCulture = ''; [System.Threading.Thread]::CurrentThread.CurrentUICulture = '';& '%~dp0build.ps1' %*; exit $LASTEXITCODE"

177
build.ps1 Normal file
View File

@ -0,0 +1,177 @@
#!/usr/bin/env powershell
#requires -version 4
<#
.SYNOPSIS
Build this repository
.DESCRIPTION
Downloads korebuild if required. Then builds the repository.
.PARAMETER Path
The folder to build. Defaults to the folder containing this script.
.PARAMETER Channel
The channel of KoreBuild to download. Overrides the value from the config file.
.PARAMETER DotNetHome
The directory where .NET Core tools will be stored.
.PARAMETER ToolsSource
The base url where build tools can be downloaded. Overrides the value from the config file.
.PARAMETER Update
Updates KoreBuild to the latest version even if a lock file is present.
.PARAMETER ConfigFile
The path to the configuration file that stores values. Defaults to version.xml.
.PARAMETER MSBuildArgs
Arguments to be passed to MSBuild
.NOTES
This function will create a file $PSScriptRoot/korebuild-lock.txt. This lock file can be committed to source, but does not have to be.
When the lockfile is not present, KoreBuild will create one using latest available version from $Channel.
The $ConfigFile is expected to be an XML file. It is optional, and the configuration values in it are optional as well.
.EXAMPLE
Example config file:
```xml
<!-- version.xml -->
<Project>
<PropertyGroup>
<KoreBuildChannel>dev</KoreBuildChannel>
<KoreBuildToolsSource>https://aspnetcore.blob.core.windows.net/buildtools</KoreBuildToolsSource>
</PropertyGroup>
</Project>
```
#>
[CmdletBinding(PositionalBinding = $false)]
param(
[string]$Path = $PSScriptRoot,
[Alias('c')]
[string]$Channel,
[Alias('d')]
[string]$DotNetHome,
[Alias('s')]
[string]$ToolsSource,
[Alias('u')]
[switch]$Update,
[string]$ConfigFile = (Join-Path $PSScriptRoot 'version.xml'),
[Parameter(ValueFromRemainingArguments = $true)]
[string[]]$MSBuildArgs
)
Set-StrictMode -Version 2
$ErrorActionPreference = 'Stop'
#
# Functions
#
function Get-KoreBuild {
$lockFile = Join-Path $Path 'korebuild-lock.txt'
if (!(Test-Path $lockFile) -or $Update) {
Get-RemoteFile "$ToolsSource/korebuild/channels/$Channel/latest.txt" $lockFile
}
$version = Get-Content $lockFile | Where-Object { $_ -like 'version:*' } | Select-Object -first 1
if (!$version) {
Write-Error "Failed to parse version from $lockFile. Expected a line that begins with 'version:'"
}
$version = $version.TrimStart('version:').Trim()
$korebuildPath = Join-Paths $DotNetHome ('buildtools', 'korebuild', $version)
if (!(Test-Path $korebuildPath)) {
Write-Host -ForegroundColor Magenta "Downloading KoreBuild $version"
New-Item -ItemType Directory -Path $korebuildPath | Out-Null
$remotePath = "$ToolsSource/korebuild/artifacts/$version/korebuild.$version.zip"
try {
$tmpfile = Join-Path ([IO.Path]::GetTempPath()) "KoreBuild-$([guid]::NewGuid()).zip"
Get-RemoteFile $remotePath $tmpfile
if (Get-Command -Name 'Expand-Archive' -ErrorAction Ignore) {
# Use built-in commands where possible as they are cross-plat compatible
Expand-Archive -Path $tmpfile -DestinationPath $korebuildPath
}
else {
# Fallback to old approach for old installations of PowerShell
Add-Type -AssemblyName System.IO.Compression.FileSystem
[System.IO.Compression.ZipFile]::ExtractToDirectory($tmpfile, $korebuildPath)
}
}
catch {
Remove-Item -Recurse -Force $korebuildPath -ErrorAction Ignore
throw
}
finally {
Remove-Item $tmpfile -ErrorAction Ignore
}
}
return $korebuildPath
}
function Join-Paths([string]$path, [string[]]$childPaths) {
$childPaths | ForEach-Object { $path = Join-Path $path $_ }
return $path
}
function Get-RemoteFile([string]$RemotePath, [string]$LocalPath) {
if ($RemotePath -notlike 'http*') {
Copy-Item $RemotePath $LocalPath
return
}
$retries = 10
while ($retries -gt 0) {
$retries -= 1
try {
Invoke-WebRequest -UseBasicParsing -Uri $RemotePath -OutFile $LocalPath
return
}
catch {
Write-Verbose "Request failed. $retries retries remaining"
}
}
Write-Error "Download failed: '$RemotePath'."
}
#
# Main
#
# Load configuration or set defaults
if (Test-Path $ConfigFile) {
[xml] $config = Get-Content $ConfigFile
if (!($Channel)) { [string] $Channel = Select-Xml -Xml $config -XPath '/Project/PropertyGroup/KoreBuildChannel' }
if (!($ToolsSource)) { [string] $ToolsSource = Select-Xml -Xml $config -XPath '/Project/PropertyGroup/KoreBuildToolsSource' }
}
if (!$DotNetHome) {
$DotNetHome = if ($env:DOTNET_HOME) { $env:DOTNET_HOME } `
elseif ($env:USERPROFILE) { Join-Path $env:USERPROFILE '.dotnet'} `
elseif ($env:HOME) {Join-Path $env:HOME '.dotnet'}`
else { Join-Path $PSScriptRoot '.dotnet'}
}
if (!$Channel) { $Channel = 'dev' }
if (!$ToolsSource) { $ToolsSource = 'https://aspnetcore.blob.core.windows.net/buildtools' }
# Execute
$korebuildPath = Get-KoreBuild
Import-Module -Force -Scope Local (Join-Path $korebuildPath 'KoreBuild.psd1')
try {
Install-Tools $ToolsSource $DotNetHome
Invoke-RepositoryBuild $Path @MSBuildArgs
}
finally {
Remove-Module 'KoreBuild' -ErrorAction Ignore
}

199
build.sh Normal file
View File

@ -0,0 +1,199 @@
#!/usr/bin/env bash
set -euo pipefail
#
# variables
#
RESET="\033[0m"
RED="\033[0;31m"
MAGENTA="\033[0;95m"
DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
[ -z "${DOTNET_HOME:-}" ] && DOTNET_HOME="$HOME/.dotnet"
config_file="$DIR/version.xml"
verbose=false
update=false
repo_path="$DIR"
channel=''
tools_source=''
#
# Functions
#
__usage() {
echo "Usage: $(basename "${BASH_SOURCE[0]}") [options] [[--] <MSBUILD_ARG>...]"
echo ""
echo "Arguments:"
echo " <MSBUILD_ARG>... Arguments passed to MSBuild. Variable number of arguments allowed."
echo ""
echo "Options:"
echo " --verbose Show verbose output."
echo " -c|--channel <CHANNEL> The channel of KoreBuild to download. Overrides the value from the config file.."
echo " --config-file <FILE> TThe path to the configuration file that stores values. Defaults to version.xml."
echo " -d|--dotnet-home <DIR> The directory where .NET Core tools will be stored. Defaults to '\$DOTNET_HOME' or '\$HOME/.dotnet."
echo " --path <PATH> The directory to build. Defaults to the directory containing the script."
echo " -s|--tools-source <URL> The base url where build tools can be downloaded. Overrides the value from the config file."
echo " -u|--update Update to the latest KoreBuild even if the lock file is present."
echo ""
echo "Description:"
echo " This function will create a file \$DIR/korebuild-lock.txt. This lock file can be committed to source, but does not have to be."
echo " When the lockfile is not present, KoreBuild will create one using latest available version from \$channel."
if [[ "${1:-}" != '--no-exit' ]]; then
exit 2
fi
}
get_korebuild() {
local version
local lock_file="$repo_path/korebuild-lock.txt"
if [ ! -f "$lock_file" ] || [ "$update" = true ]; then
__get_remote_file "$tools_source/korebuild/channels/$channel/latest.txt" "$lock_file"
fi
version="$(grep 'version:*' -m 1 "$lock_file")"
if [[ "$version" == '' ]]; then
__error "Failed to parse version from $lock_file. Expected a line that begins with 'version:'"
return 1
fi
version="$(echo "${version#version:}" | sed -e 's/^[[:space:]]*//' -e 's/[[:space:]]*$//')"
local korebuild_path="$DOTNET_HOME/buildtools/korebuild/$version"
{
if [ ! -d "$korebuild_path" ]; then
mkdir -p "$korebuild_path"
local remote_path="$tools_source/korebuild/artifacts/$version/korebuild.$version.zip"
tmpfile="$(mktemp)"
echo -e "${MAGENTA}Downloading KoreBuild ${version}${RESET}"
if __get_remote_file "$remote_path" "$tmpfile"; then
unzip -q -d "$korebuild_path" "$tmpfile"
fi
rm "$tmpfile" || true
fi
source "$korebuild_path/KoreBuild.sh"
} || {
if [ -d "$korebuild_path" ]; then
echo "Cleaning up after failed installation"
rm -rf "$korebuild_path" || true
fi
return 1
}
}
__error() {
echo -e "${RED}$*${RESET}" 1>&2
}
__machine_has() {
hash "$1" > /dev/null 2>&1
return $?
}
__get_remote_file() {
local remote_path=$1
local local_path=$2
if [[ "$remote_path" != 'http'* ]]; then
cp "$remote_path" "$local_path"
return 0
fi
local failed=false
if __machine_has wget; then
wget --tries 10 --quiet -O "$local_path" "$remote_path" || failed=true
else
failed=true
fi
if [ "$failed" = true ] && __machine_has curl; then
failed=false
curl --retry 10 -sSL -f --create-dirs -o "$local_path" "$remote_path" || failed=true
fi
if [ "$failed" = true ]; then
__error "Download failed: $remote_path" 1>&2
return 1
fi
}
__read_dom () { local IFS=\> ; read -r -d \< ENTITY CONTENT ;}
#
# main
#
while [[ $# -gt 0 ]]; do
case $1 in
-\?|-h|--help)
__usage --no-exit
exit 0
;;
-c|--channel|-Channel)
shift
channel="${1:-}"
[ -z "$channel" ] && __usage
;;
--config-file|-ConfigFile)
shift
config_file="${1:-}"
[ -z "$config_file" ] && __usage
;;
-d|--dotnet-home|-DotNetHome)
shift
DOTNET_HOME="${1:-}"
[ -z "$DOTNET_HOME" ] && __usage
;;
--path|-Path)
shift
repo_path="${1:-}"
[ -z "$repo_path" ] && __usage
;;
-s|--tools-source|-ToolsSource)
shift
tools_source="${1:-}"
[ -z "$tools_source" ] && __usage
;;
-u|--update|-Update)
update=true
;;
--verbose|-Verbose)
verbose=true
;;
--)
shift
break
;;
*)
break
;;
esac
shift
done
if ! __machine_has unzip; then
__error 'Missing required command: unzip'
exit 1
fi
if ! __machine_has curl && ! __machine_has wget; then
__error 'Missing required command. Either wget or curl is required.'
exit 1
fi
if [ -f "$config_file" ]; then
comment=false
while __read_dom; do
if [ "$comment" = true ]; then [[ $CONTENT == *'-->'* ]] && comment=false ; continue; fi
if [[ $ENTITY == '!--'* ]]; then comment=true; continue; fi
if [ -z "$channel" ] && [[ $ENTITY == "KoreBuildChannel" ]]; then channel=$CONTENT; fi
if [ -z "$tools_source" ] && [[ $ENTITY == "KoreBuildToolsSource" ]]; then tools_source=$CONTENT; fi
done < "$config_file"
fi
[ -z "$channel" ] && channel='dev'
[ -z "$tools_source" ] && tools_source='https://aspnetcore.blob.core.windows.net/buildtools'
get_korebuild
install_tools "$tools_source" "$DOTNET_HOME"
invoke_repository_build "$repo_path" "$@"

6
build/dependencies.props Normal file
View File

@ -0,0 +1,6 @@
<Project>
<PropertyGroup>
<XunitAnalyzersVersion>0.6.1</XunitAnalyzersVersion>
<XunitVersion>2.3.0-beta4-build3742</XunitVersion>
</PropertyGroup>
</Project>

503
dotnet-install.ps1 vendored
View File

@ -1,503 +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.
#
<#
.SYNOPSIS
Installs dotnet cli
.DESCRIPTION
Installs dotnet cli. If dotnet installation already exists in the given directory
it will update it only if the requested version differs from the one already installed.
.PARAMETER Channel
Default: LTS
Download from the Channel specified. Possible values:
- Current - most current release
- LTS - most current supported release
- 2-part version in a format A.B - represents a specific release
examples: 2.0; 1.0
- Branch name
examples: release/2.0.0; Master
.PARAMETER Version
Default: latest
Represents a build version on specific channel. Possible values:
- latest - most latest build on specific channel
- coherent - most latest coherent build on specific channel
coherent applies only to SDK downloads
- 3-part version in a format A.B.C - represents specific version of build
examples: 2.0.0-preview2-006120; 1.1.0
.PARAMETER InstallDir
Default: %LocalAppData%\Microsoft\dotnet
Path to where to install dotnet. Note that binaries will be placed directly in a given directory.
.PARAMETER Architecture
Default: <auto> - this value represents currently running OS architecture
Architecture of dotnet binaries to be installed.
Possible values are: <auto>, x64 and x86
.PARAMETER SharedRuntime
Default: false
Installs just the shared runtime bits, not the entire SDK
.PARAMETER DryRun
If set it will not perform installation but instead display what command line to use to consistently install
currently requested version of dotnet cli. In example if you specify version 'latest' it will display a link
with specific version so that this command can be used deterministicly in a build script.
It also displays binaries location if you prefer to install or download it yourself.
.PARAMETER NoPath
By default this script will set environment variable PATH for the current process to the binaries folder inside installation folder.
If set it will display binaries location but not set any environment variable.
.PARAMETER Verbose
Displays diagnostics information.
.PARAMETER AzureFeed
Default: https://dotnetcli.azureedge.net/dotnet
This parameter typically is not changed by the user.
It allows to change URL for the Azure feed used by this installer.
.PARAMETER UncachedFeed
This parameter typically is not changed by the user.
It allows to change URL for the Uncached feed used by this installer.
.PARAMETER ProxyAddress
If set, the installer will use the proxy when making web requests
.PARAMETER ProxyUseDefaultCredentials
Default: false
Use default credentials, when using proxy address.
#>
[cmdletbinding()]
param(
[string]$Channel="release/2.0.0",
[string]$Version="2.0.1-servicing-006924",
[string]$InstallDir="<auto>",
[string]$Architecture="<auto>",
[switch]$SharedRuntime,
[switch]$DryRun,
[switch]$NoPath,
[string]$AzureFeed="https://dotnetcli.azureedge.net/dotnet",
[string]$UncachedFeed="https://dotnetcli.blob.core.windows.net/dotnet",
[string]$ProxyAddress,
[switch]$ProxyUseDefaultCredentials
)
Set-StrictMode -Version Latest
$ErrorActionPreference="Stop"
$ProgressPreference="SilentlyContinue"
$BinFolderRelativePath=""
# example path with regex: shared/1.0.0-beta-12345/somepath
$VersionRegEx="/\d+\.\d+[^/]+/"
$OverrideNonVersionedFiles=$true
function Say($str) {
Write-Output "dotnet-install: $str"
}
function Say-Verbose($str) {
Write-Verbose "dotnet-install: $str"
}
function Say-Invocation($Invocation) {
$command = $Invocation.MyCommand;
$args = (($Invocation.BoundParameters.Keys | foreach { "-$_ `"$($Invocation.BoundParameters[$_])`"" }) -join " ")
Say-Verbose "$command $args"
}
function Invoke-With-Retry([ScriptBlock]$ScriptBlock, [int]$MaxAttempts = 3, [int]$SecondsBetweenAttempts = 1) {
$Attempts = 0
while ($true) {
try {
return $ScriptBlock.Invoke()
}
catch {
$Attempts++
if ($Attempts -lt $MaxAttempts) {
Start-Sleep $SecondsBetweenAttempts
}
else {
throw
}
}
}
}
function Get-Machine-Architecture() {
Say-Invocation $MyInvocation
# possible values: AMD64, IA64, x86
return $ENV:PROCESSOR_ARCHITECTURE
}
# TODO: Architecture and CLIArchitecture should be unified
function Get-CLIArchitecture-From-Architecture([string]$Architecture) {
Say-Invocation $MyInvocation
switch ($Architecture.ToLower()) {
{ $_ -eq "<auto>" } { return Get-CLIArchitecture-From-Architecture $(Get-Machine-Architecture) }
{ ($_ -eq "amd64") -or ($_ -eq "x64") } { return "x64" }
{ $_ -eq "x86" } { return "x86" }
default { throw "Architecture not supported. If you think this is a bug, please report it at https://github.com/dotnet/cli/issues" }
}
}
function Get-Version-Info-From-Version-Text([string]$VersionText) {
Say-Invocation $MyInvocation
$Data = @($VersionText.Split([char[]]@(), [StringSplitOptions]::RemoveEmptyEntries));
$VersionInfo = @{}
$VersionInfo.CommitHash = $Data[0].Trim()
$VersionInfo.Version = $Data[1].Trim()
return $VersionInfo
}
function Load-Assembly([string] $Assembly) {
try {
Add-Type -Assembly $Assembly | Out-Null
}
catch {
# On Nano Server, Powershell Core Edition is used. Add-Type is unable to resolve base class assemblies because they are not GAC'd.
# Loading the base class assemblies is not unnecessary as the types will automatically get resolved.
}
}
function GetHTTPResponse([Uri] $Uri)
{
Invoke-With-Retry(
{
$HttpClient = $null
try {
# HttpClient is used vs Invoke-WebRequest in order to support Nano Server which doesn't support the Invoke-WebRequest cmdlet.
Load-Assembly -Assembly System.Net.Http
if(-not $ProxyAddress)
{
# Despite no proxy being explicitly specified, we may still be behind a default proxy
$DefaultProxy = [System.Net.WebRequest]::DefaultWebProxy;
if($DefaultProxy -and (-not $DefaultProxy.IsBypassed($Uri))){
$ProxyAddress = $DefaultProxy.GetProxy($Uri).OriginalString
$ProxyUseDefaultCredentials = $true
}
}
if($ProxyAddress){
$HttpClientHandler = New-Object System.Net.Http.HttpClientHandler
$HttpClientHandler.Proxy = New-Object System.Net.WebProxy -Property @{Address=$ProxyAddress;UseDefaultCredentials=$ProxyUseDefaultCredentials}
$HttpClient = New-Object System.Net.Http.HttpClient -ArgumentList $HttpClientHandler
}
else {
$HttpClient = New-Object System.Net.Http.HttpClient
}
# Default timeout for HttpClient is 100s. For a 50 MB download this assumes 500 KB/s average, any less will time out
# 10 minutes allows it to work over much slower connections.
$HttpClient.Timeout = New-TimeSpan -Minutes 10
$Response = $HttpClient.GetAsync($Uri).Result
if (($Response -eq $null) -or (-not ($Response.IsSuccessStatusCode)))
{
$ErrorMsg = "Failed to download $Uri."
if ($Response -ne $null)
{
$ErrorMsg += " $Response"
}
throw $ErrorMsg
}
return $Response
}
finally {
if ($HttpClient -ne $null) {
$HttpClient.Dispose()
}
}
})
}
function Get-Latest-Version-Info([string]$AzureFeed, [string]$Channel, [bool]$Coherent) {
Say-Invocation $MyInvocation
$VersionFileUrl = $null
if ($SharedRuntime) {
$VersionFileUrl = "$UncachedFeed/Runtime/$Channel/latest.version"
}
else {
if ($Coherent) {
$VersionFileUrl = "$UncachedFeed/Sdk/$Channel/latest.coherent.version"
}
else {
$VersionFileUrl = "$UncachedFeed/Sdk/$Channel/latest.version"
}
}
$Response = GetHTTPResponse -Uri $VersionFileUrl
$StringContent = $Response.Content.ReadAsStringAsync().Result
switch ($Response.Content.Headers.ContentType) {
{ ($_ -eq "application/octet-stream") } { $VersionText = [Text.Encoding]::UTF8.GetString($StringContent) }
{ ($_ -eq "text/plain") } { $VersionText = $StringContent }
{ ($_ -eq "text/plain; charset=UTF-8") } { $VersionText = $StringContent }
default { throw "``$Response.Content.Headers.ContentType`` is an unknown .version file content type." }
}
$VersionInfo = Get-Version-Info-From-Version-Text $VersionText
return $VersionInfo
}
function Get-Specific-Version-From-Version([string]$AzureFeed, [string]$Channel, [string]$Version) {
Say-Invocation $MyInvocation
switch ($Version.ToLower()) {
{ $_ -eq "latest" } {
$LatestVersionInfo = Get-Latest-Version-Info -AzureFeed $AzureFeed -Channel $Channel -Coherent $False
return $LatestVersionInfo.Version
}
{ $_ -eq "coherent" } {
$LatestVersionInfo = Get-Latest-Version-Info -AzureFeed $AzureFeed -Channel $Channel -Coherent $True
return $LatestVersionInfo.Version
}
default { return $Version }
}
}
function Get-Download-Link([string]$AzureFeed, [string]$Channel, [string]$SpecificVersion, [string]$CLIArchitecture) {
Say-Invocation $MyInvocation
if ($SharedRuntime) {
$PayloadURL = "$AzureFeed/Runtime/$SpecificVersion/dotnet-runtime-$SpecificVersion-win-$CLIArchitecture.zip"
}
else {
$PayloadURL = "$AzureFeed/Sdk/$SpecificVersion/dotnet-sdk-$SpecificVersion-win-$CLIArchitecture.zip"
}
Say-Verbose "Constructed primary payload URL: $PayloadURL"
return $PayloadURL
}
function Get-LegacyDownload-Link([string]$AzureFeed, [string]$Channel, [string]$SpecificVersion, [string]$CLIArchitecture) {
Say-Invocation $MyInvocation
if ($SharedRuntime) {
$PayloadURL = "$AzureFeed/Runtime/$SpecificVersion/dotnet-win-$CLIArchitecture.$SpecificVersion.zip"
}
else {
$PayloadURL = "$AzureFeed/Sdk/$SpecificVersion/dotnet-dev-win-$CLIArchitecture.$SpecificVersion.zip"
}
Say-Verbose "Constructed legacy payload URL: $PayloadURL"
return $PayloadURL
}
function Get-User-Share-Path() {
Say-Invocation $MyInvocation
$InstallRoot = $env:DOTNET_INSTALL_DIR
if (!$InstallRoot) {
$InstallRoot = "$env:LocalAppData\Microsoft\dotnet"
}
return $InstallRoot
}
function Resolve-Installation-Path([string]$InstallDir) {
Say-Invocation $MyInvocation
if ($InstallDir -eq "<auto>") {
return Get-User-Share-Path
}
return $InstallDir
}
function Get-Version-Info-From-Version-File([string]$InstallRoot, [string]$RelativePathToVersionFile) {
Say-Invocation $MyInvocation
$VersionFile = Join-Path -Path $InstallRoot -ChildPath $RelativePathToVersionFile
Say-Verbose "Local version file: $VersionFile"
if (Test-Path $VersionFile) {
$VersionText = cat $VersionFile
Say-Verbose "Local version file text: $VersionText"
return Get-Version-Info-From-Version-Text $VersionText
}
Say-Verbose "Local version file not found."
return $null
}
function Is-Dotnet-Package-Installed([string]$InstallRoot, [string]$RelativePathToPackage, [string]$SpecificVersion) {
Say-Invocation $MyInvocation
$DotnetPackagePath = Join-Path -Path $InstallRoot -ChildPath $RelativePathToPackage | Join-Path -ChildPath $SpecificVersion
Say-Verbose "Is-Dotnet-Package-Installed: Path to a package: $DotnetPackagePath"
return Test-Path $DotnetPackagePath -PathType Container
}
function Get-Absolute-Path([string]$RelativeOrAbsolutePath) {
# Too much spam
# Say-Invocation $MyInvocation
return $ExecutionContext.SessionState.Path.GetUnresolvedProviderPathFromPSPath($RelativeOrAbsolutePath)
}
function Get-Path-Prefix-With-Version($path) {
$match = [regex]::match($path, $VersionRegEx)
if ($match.Success) {
return $entry.FullName.Substring(0, $match.Index + $match.Length)
}
return $null
}
function Get-List-Of-Directories-And-Versions-To-Unpack-From-Dotnet-Package([System.IO.Compression.ZipArchive]$Zip, [string]$OutPath) {
Say-Invocation $MyInvocation
$ret = @()
foreach ($entry in $Zip.Entries) {
$dir = Get-Path-Prefix-With-Version $entry.FullName
if ($dir -ne $null) {
$path = Get-Absolute-Path $(Join-Path -Path $OutPath -ChildPath $dir)
if (-Not (Test-Path $path -PathType Container)) {
$ret += $dir
}
}
}
$ret = $ret | Sort-Object | Get-Unique
$values = ($ret | foreach { "$_" }) -join ";"
Say-Verbose "Directories to unpack: $values"
return $ret
}
# Example zip content and extraction algorithm:
# Rule: files if extracted are always being extracted to the same relative path locally
# .\
# a.exe # file does not exist locally, extract
# b.dll # file exists locally, override only if $OverrideFiles set
# aaa\ # same rules as for files
# ...
# abc\1.0.0\ # directory contains version and exists locally
# ... # do not extract content under versioned part
# abc\asd\ # same rules as for files
# ...
# def\ghi\1.0.1\ # directory contains version and does not exist locally
# ... # extract content
function Extract-Dotnet-Package([string]$ZipPath, [string]$OutPath) {
Say-Invocation $MyInvocation
Load-Assembly -Assembly System.IO.Compression.FileSystem
Set-Variable -Name Zip
try {
$Zip = [System.IO.Compression.ZipFile]::OpenRead($ZipPath)
$DirectoriesToUnpack = Get-List-Of-Directories-And-Versions-To-Unpack-From-Dotnet-Package -Zip $Zip -OutPath $OutPath
foreach ($entry in $Zip.Entries) {
$PathWithVersion = Get-Path-Prefix-With-Version $entry.FullName
if (($PathWithVersion -eq $null) -Or ($DirectoriesToUnpack -contains $PathWithVersion)) {
$DestinationPath = Get-Absolute-Path $(Join-Path -Path $OutPath -ChildPath $entry.FullName)
$DestinationDir = Split-Path -Parent $DestinationPath
$OverrideFiles=$OverrideNonVersionedFiles -Or (-Not (Test-Path $DestinationPath))
if ((-Not $DestinationPath.EndsWith("\")) -And $OverrideFiles) {
New-Item -ItemType Directory -Force -Path $DestinationDir | Out-Null
[System.IO.Compression.ZipFileExtensions]::ExtractToFile($entry, $DestinationPath, $OverrideNonVersionedFiles)
}
}
}
}
finally {
if ($Zip -ne $null) {
$Zip.Dispose()
}
}
}
function DownloadFile([Uri]$Uri, [string]$OutPath) {
$Stream = $null
try {
$Response = GetHTTPResponse -Uri $Uri
$Stream = $Response.Content.ReadAsStreamAsync().Result
$File = [System.IO.File]::Create($OutPath)
$Stream.CopyTo($File)
$File.Close()
}
finally {
if ($Stream -ne $null) {
$Stream.Dispose()
}
}
}
function Prepend-Sdk-InstallRoot-To-Path([string]$InstallRoot, [string]$BinFolderRelativePath) {
$BinPath = Get-Absolute-Path $(Join-Path -Path $InstallRoot -ChildPath $BinFolderRelativePath)
if (-Not $NoPath) {
Say "Adding to current process PATH: `"$BinPath`". Note: This change will not be visible if PowerShell was run as a child process."
$env:path = "$BinPath;" + $env:path
}
else {
Say "Binaries of dotnet can be found in $BinPath"
}
}
$CLIArchitecture = Get-CLIArchitecture-From-Architecture $Architecture
$SpecificVersion = Get-Specific-Version-From-Version -AzureFeed $AzureFeed -Channel $Channel -Version $Version
$DownloadLink = Get-Download-Link -AzureFeed $AzureFeed -Channel $Channel -SpecificVersion $SpecificVersion -CLIArchitecture $CLIArchitecture
$LegacyDownloadLink = Get-LegacyDownload-Link -AzureFeed $AzureFeed -Channel $Channel -SpecificVersion $SpecificVersion -CLIArchitecture $CLIArchitecture
if ($DryRun) {
Say "Payload URLs:"
Say "Primary - $DownloadLink"
Say "Legacy - $LegacyDownloadLink"
Say "Repeatable invocation: .\$($MyInvocation.MyCommand) -Version $SpecificVersion -Channel $Channel -Architecture $CLIArchitecture -InstallDir $InstallDir"
exit 0
}
$InstallRoot = Resolve-Installation-Path $InstallDir
Say-Verbose "InstallRoot: $InstallRoot"
$IsSdkInstalled = Is-Dotnet-Package-Installed -InstallRoot $InstallRoot -RelativePathToPackage "sdk" -SpecificVersion $SpecificVersion
Say-Verbose ".NET SDK installed? $IsSdkInstalled"
if ($IsSdkInstalled) {
Say ".NET SDK version $SpecificVersion is already installed."
Prepend-Sdk-InstallRoot-To-Path -InstallRoot $InstallRoot -BinFolderRelativePath $BinFolderRelativePath
exit 0
}
New-Item -ItemType Directory -Force -Path $InstallRoot | Out-Null
$installDrive = $((Get-Item $InstallRoot).PSDrive.Name);
Write-Output "${installDrive}:";
$free = Get-CimInstance -Class win32_logicaldisk | where Deviceid -eq "${installDrive}:"
if ($free.Freespace / 1MB -le 100 ) {
Say "There is not enough disk space on drive ${installDrive}:"
exit 0
}
$ZipPath = [System.IO.Path]::GetTempFileName()
Say-Verbose "Zip path: $ZipPath"
Say "Downloading link: $DownloadLink"
try {
DownloadFile -Uri $DownloadLink -OutPath $ZipPath
}
catch {
Say "Cannot download: $DownloadLink"
$DownloadLink = $LegacyDownloadLink
$ZipPath = [System.IO.Path]::GetTempFileName()
Say-Verbose "Legacy zip path: $ZipPath"
Say "Downloading legacy link: $DownloadLink"
DownloadFile -Uri $DownloadLink -OutPath $ZipPath
}
Say "Extracting zip from $DownloadLink"
Extract-Dotnet-Package -ZipPath $ZipPath -OutPath $InstallRoot
Remove-Item $ZipPath
Prepend-Sdk-InstallRoot-To-Path -InstallRoot $InstallRoot -BinFolderRelativePath $BinFolderRelativePath
Say "Installation finished"
exit 0

View File

@ -1,5 +0,0 @@
@echo off
if not defined TemplatesRoot (
echo Initializing templates environment
call %~dp0\TemplatesEnv.cmd
)

View File

@ -1,39 +0,0 @@
@echo off
if defined ProgramFiles(x86) (
set "TemplatesProgramFiles=%ProgramFiles(x86)%"
) else (
set "TemplatesProgramFiles=%ProgramFiles%"
)
if not defined DNX_PACKAGES (
set DNX_PACKAGES=%~dp0\..\packages
)
if not defined DOTNET_INSTALL_DIR (
set DOTNET_INSTALL_DIR=%LocalAppData%\Microsoft\dotnet\
)
if not defined DOTNET_VERSION (
set DOTNET_VERSION=2.0.1-servicing-006924
)
if exist "%TemplatesProgramFiles%\Microsoft Visual Studio\Preview\MSBuild\15.0\Bin\MSBuild.exe" (
set "TemplatesVSVersion=15.0"
set TemplatesMSBuildPath="%TemplatesProgramFiles%\Microsoft Visual Studio\Preview\MSBuild\15.0\Bin"
) else (
set "TemplatesVSVersion=14.0"
set TemplatesMSBuildPath="%TemplatesProgramFiles%\MSBuild\14.0\Bin"
)
set "TemplatesRoot=%~dp0"
set "TemplatesRoot=%TemplatesRoot:~0,-7%"
set "TemplatesBin=%TemplatesRoot%\bin\"
set "TemplatesIntermediate=%TemplatesRoot%\obj\"
set "TemplatesReferences=%TemplatesRoot%\references\"
set "TemplatesSource=%TemplatesRoot%\src\"
set "TemplatesTools=%TemplatesRoot%\tools\"
set "PATH=%PATH%;%TemplatesMSBuildPath%"
set "PATH=%PATH%;%TemplatesTools%"
set "PATH=%DOTNET_INSTALL_DIR%;%PATH%"

View File

@ -1,13 +0,0 @@
@echo off
call %~dp0\EnsureTemplatesEnv.cmd
echo dotnet version:
dotnet --version
dotnet msbuild %TemplatesRoot%\template_feed\Template.proj /t:Build;Test
if errorlevel 0 exit /b 0
:ERROR
endlocal
exit /b 1