diff --git a/build.ps1 b/build.ps1 index c2c56fd..e6584c6 100755 --- a/build.ps1 +++ b/build.ps1 @@ -4,12 +4,9 @@ param( [Alias('p')] [string]$Path = $PSScriptRoot, + [string]$ConfigFile = $null, [Alias('d')] - [string]$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'} ), + [string]$DotNetHome = $null, [Alias('s')] [string]$ToolsSource = 'https://aspnetcore.blob.core.windows.net/buildtools', [Parameter(ValueFromRemainingArguments = $true)] @@ -18,10 +15,21 @@ param( $ErrorActionPreference = 'Stop' +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 (!($ConfigFile)) { + $ConfigFile = Join-Path $Path 'korebuild.json' +} + try { Import-Module -Force -Scope Local "$PSScriptRoot/files/KoreBuild/KoreBuild.psd1" - Set-KoreBuildSettings -ToolsSource $ToolsSource -DotNetHome $DotNetHome -RepoPath $Path + Set-KoreBuildSettings -ToolsSource $ToolsSource -DotNetHome $DotNetHome -RepoPath $Path -ConfigFile $ConfigFile Invoke-KoreBuildCommand "default-build" @Arguments } finally { diff --git a/build.sh b/build.sh index d7a6e31..b64a5c5 100755 --- a/build.sh +++ b/build.sh @@ -22,6 +22,7 @@ __usage() { # [ -z "${DOTNET_HOME:-}" ] && DOTNET_HOME="$HOME/.dotnet" +config_file="$DIR/korebuild.json" tools_source='https://aspnetcore.blob.core.windows.net/buildtools' verbose=false while [[ $# -gt 0 ]]; do @@ -53,6 +54,6 @@ while [[ $# -gt 0 ]]; do shift done -set_korebuildsettings "$tools_source" "$DOTNET_HOME" "$DIR" +set_korebuildsettings "$tools_source" "$DOTNET_HOME" "$DIR" "$config_file" invoke_korebuild_command "default-build" "$@" diff --git a/build/common.props b/build/common.props index bfae37d..a9293c6 100644 --- a/build/common.props +++ b/build/common.props @@ -1,6 +1,6 @@ - + diff --git a/build/repo.props b/build/repo.props index 7675f64..0392cdf 100644 --- a/build/repo.props +++ b/build/repo.props @@ -1,5 +1,5 @@ - + $(VersionPrefix) diff --git a/files/KoreBuild/KoreBuild.sh b/files/KoreBuild/KoreBuild.sh index fd2b8bf..edd2f52 100755 --- a/files/KoreBuild/KoreBuild.sh +++ b/files/KoreBuild/KoreBuild.sh @@ -10,6 +10,7 @@ set_korebuildsettings() { tools_source=$1 dotnet_home=$2 repo_path=$3 + local config_file="${4:-}" # optional. Not used yet. [ -z "${dot_net_home:-}" ] && dot_net_home="$HOME/.dotnet" [ -z "${tools_source:-}" ] && tools_source='https://aspnetcore.blob.core.windows.net/buildtools' @@ -18,7 +19,7 @@ set_korebuildsettings() { } invoke_korebuild_command(){ - local command=$1 + local command="${1:-}" shift if [ "$command" = "default-build" ]; then diff --git a/files/KoreBuild/scripts/KoreBuild.psm1 b/files/KoreBuild/scripts/KoreBuild.psm1 index 36f0983..8bd3a5b 100644 --- a/files/KoreBuild/scripts/KoreBuild.psm1 +++ b/files/KoreBuild/scripts/KoreBuild.psm1 @@ -248,12 +248,19 @@ The directory where tools will be stored on the local machine. .PARAMETER RepoPath The directory to execute the command against. + +.PARAMETER ConfigFile +The korebuild.json file. (Ignored right now: may be used in the future) #> function Set-KoreBuildSettings( + [Parameter()] [string]$ToolsSource, + [Parameter()] [string]$DotNetHome, - [string]$RepoPath -) + [Parameter()] + [string]$RepoPath, + [Parameter()] + [string]$ConfigFile = $null) { if (!$DotNetHome) { $DotNetHome = if ($env:DOTNET_HOME) { $env:DOTNET_HOME } ` diff --git a/files/KoreBuild/scripts/common.sh b/files/KoreBuild/scripts/common.sh index 10565f5..be031e4 100644 --- a/files/KoreBuild/scripts/common.sh +++ b/files/KoreBuild/scripts/common.sh @@ -41,7 +41,7 @@ __exec() { local exit_code=$? set -e if [ $exit_code -ne 0 ]; then - __error "<<< $cmdname failed with exit code $exit_code" + __error "$cmdname failed with exit code $exit_code" elif [ "$__is_verbose" = true ]; then echo -e "${GREEN}<<< $cmdname [$exit_code]${RESET}" fi diff --git a/korebuild.json b/korebuild.json new file mode 100644 index 0000000..551cc41 --- /dev/null +++ b/korebuild.json @@ -0,0 +1,4 @@ +{ + "$schema": "./tools/korebuild.schema.json", + "channel": "dev" +} diff --git a/push.ps1 b/push.ps1 index 24d9cd6..8140e2e 100644 --- a/push.ps1 +++ b/push.ps1 @@ -20,7 +20,7 @@ $artifacts = Join-Path $PSScriptRoot 'artifacts' Get-ChildItem "$artifacts/build/*.nupkg" | Push-NuGetPackage -Feed $NuGetFeed -ApiKey $env:APIKEY -WhatIf:$WhatIfPreference -$settings = [xml] (Get-Content (Join-Path $PSScriptRoot 'version.xml')) +$settings = [xml] (Get-Content (Join-Path $PSScriptRoot 'version.props')) $channelName = $settings.Project.PropertyGroup.KoreBuildChannel Write-Host "Pushing azure artifacts for '$channelName' channel" diff --git a/scripts/bootstrapper/build.sh b/scripts/bootstrapper/build.sh index 17a3da3..74c8ed4 100755 --- a/scripts/bootstrapper/build.sh +++ b/scripts/bootstrapper/build.sh @@ -1,5 +1,6 @@ #!/usr/bin/env bash set -euo pipefail - -./run.sh default-build "$@" +DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" +chmod +x "$DIR/run.sh" +"$DIR/run.sh" default-build "$@" diff --git a/scripts/bootstrapper/run.ps1 b/scripts/bootstrapper/run.ps1 old mode 100644 new mode 100755 index cbdd9ab..49c2899 --- a/scripts/bootstrapper/run.ps1 +++ b/scripts/bootstrapper/run.ps1 @@ -27,7 +27,7 @@ The base url where build tools can be downloaded. Overrides the value from the c 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. +The path to the configuration file that stores values. Defaults to korebuild.json. .PARAMETER Arguments Arguments to be passed to the command @@ -36,18 +36,17 @@ Arguments to be passed to the command 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. +The $ConfigFile is expected to be an JSON file. It is optional, and the configuration values in it are optional as well. Any options set +in the file are overridden by command line parameters. .EXAMPLE Example config file: -```xml - - - - dev - https://aspnetcore.blob.core.windows.net/buildtools - - +```json +{ + "$schema": "https://raw.githubusercontent.com/aspnet/BuildTools/dev/tools/korebuild.schema.json", + "channel": "dev", + "toolsSource": "https://aspnetcore.blob.core.windows.net/buildtools" +} ``` #> [CmdletBinding(PositionalBinding = $false)] @@ -63,7 +62,7 @@ param( [string]$ToolsSource, [Alias('u')] [switch]$Update, - [string]$ConfigFile = (Join-Path $PSScriptRoot 'version.xml'), + [string]$ConfigFile, [Parameter(ValueFromRemainingArguments = $true)] [string[]]$Arguments ) @@ -152,10 +151,20 @@ function Get-RemoteFile([string]$RemotePath, [string]$LocalPath) { # Load configuration or set defaults +$Path = Resolve-Path $Path +if (!$ConfigFile) { $ConfigFile = Join-Path $Path 'korebuild.json' } + 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' } + try { + $config = Get-Content -Raw -Encoding UTF8 -Path $ConfigFile | ConvertFrom-Json + if ($config) { + if (!($Channel) -and (Get-Member -Name 'channel' -InputObject $config)) { [string] $Channel = $config.channel } + if (!($ToolsSource) -and (Get-Member -Name 'toolsSource' -InputObject $config)) { [string] $ToolsSource = $config.toolsSource} + } + } catch { + Write-Warning "$ConfigFile could not be read. Its settings will be ignored." + Write-Warning $Error[0] + } } if (!$DotNetHome) { @@ -174,7 +183,7 @@ $korebuildPath = Get-KoreBuild Import-Module -Force -Scope Local (Join-Path $korebuildPath 'KoreBuild.psd1') try { - Set-KoreBuildSettings -ToolsSource $ToolsSource -DotNetHome $DotNetHome -RepoPath $Path + Set-KoreBuildSettings -ToolsSource $ToolsSource -DotNetHome $DotNetHome -RepoPath $Path -ConfigFile $ConfigFile Invoke-KoreBuildCommand $Command @Arguments } finally { diff --git a/scripts/bootstrapper/run.sh b/scripts/bootstrapper/run.sh index 82049ac..697508a 100755 --- a/scripts/bootstrapper/run.sh +++ b/scripts/bootstrapper/run.sh @@ -8,10 +8,10 @@ set -euo pipefail RESET="\033[0m" RED="\033[0;31m" +YELLOW="\033[0;33m" 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" @@ -31,7 +31,7 @@ __usage() { echo "Options:" echo " --verbose Show verbose output." echo " -c|--channel The channel of KoreBuild to download. Overrides the value from the config file.." - echo " --config-file TThe path to the configuration file that stores values. Defaults to version.xml." + echo " --config-file TThe path to the configuration file that stores values. Defaults to korebuild.json." echo " -d|--dotnet-home The directory where .NET Core tools will be stored. Defaults to '\$DOTNET_HOME' or '\$HOME/.dotnet." echo " --path The directory to build. Defaults to the directory containing the script." echo " -s|--tools-source The base url where build tools can be downloaded. Overrides the value from the config file." @@ -83,7 +83,11 @@ get_korebuild() { } __error() { - echo -e "${RED}$*${RESET}" 1>&2 + echo -e "${RED}error: $*${RESET}" 1>&2 +} + +__warn() { + echo -e "${YELLOW}warning: $*${RESET}" } __machine_has() { @@ -118,11 +122,10 @@ __get_remote_file() { fi } -__read_dom () { local IFS=\> ; read -r -d \< ENTITY CONTENT ;} - # # main # + command="${1:-}" shift @@ -141,6 +144,10 @@ while [[ $# -gt 0 ]]; do shift config_file="${1:-}" [ -z "$config_file" ] && __usage + if [ ! -f "$config_file" ]; then + __error "Invalid value for --config-file. $config_file does not exist." + exit 1 + fi ;; -d|--dotnet-home|-DotNetHome) shift @@ -184,21 +191,33 @@ if ! __machine_has curl && ! __machine_has wget; then exit 1 fi +[ -z "${config_file:-}" ] && config_file="$repo_path/korebuild.json" 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" + if __machine_has jq ; then + if jq '.' "$config_file" >/dev/null ; then + config_channel="$(jq -r 'select(.channel!=null) | .channel' "$config_file")" + config_tools_source="$(jq -r 'select(.toolsSource!=null) | .toolsSource' "$config_file")" + else + __warn "$config_file is invalid JSON. Its settings will be ignored." + fi + elif __machine_has python ; then + if python -c "import json,codecs;obj=json.load(codecs.open('$config_file', 'r', 'utf-8-sig'))" >/dev/null ; then + config_channel="$(python -c "import json,codecs;obj=json.load(codecs.open('$config_file', 'r', 'utf-8-sig'));print(obj['channel'] if 'channel' in obj else '')")" + config_tools_source="$(python -c "import json,codecs;obj=json.load(codecs.open('$config_file', 'r', 'utf-8-sig'));print(obj['toolsSource'] if 'toolsSource' in obj else '')")" + else + __warn "$config_file is invalid JSON. Its settings will be ignored." + fi + else + __warn 'Missing required command: jq or pyton. Could not parse the JSON file. Its settings will be ignored.' + fi + + [ ! -z "${config_channel:-}" ] && channel="$config_channel" + [ ! -z "${config_tools_source:-}" ] && tools_source="$config_tools_source" fi [ -z "$channel" ] && channel='dev' [ -z "$tools_source" ] && tools_source='https://aspnetcore.blob.core.windows.net/buildtools' get_korebuild - -set_korebuildsettings "$tools_source" "$DOTNET_HOME" "$repo_path" - +set_korebuildsettings "$tools_source" "$DOTNET_HOME" "$repo_path" "$config_file" invoke_korebuild_command "$command" "$@" diff --git a/testassets/SimpleRepo/Directory.Build.props b/testassets/SimpleRepo/Directory.Build.props new file mode 100644 index 0000000..cc8828f --- /dev/null +++ b/testassets/SimpleRepo/Directory.Build.props @@ -0,0 +1,3 @@ + + + diff --git a/testassets/SimpleRepo/korebuild.json b/testassets/SimpleRepo/korebuild.json new file mode 100644 index 0000000..bd5d51a --- /dev/null +++ b/testassets/SimpleRepo/korebuild.json @@ -0,0 +1,4 @@ +{ + "$schema": "https://raw.githubusercontent.com/aspnet/BuildTools/dev/tools/korebuild.schema.json", + "channel": "dev" +} diff --git a/testassets/SimpleRepo/src/Simple.Lib/Simple.Lib.csproj b/testassets/SimpleRepo/src/Simple.Lib/Simple.Lib.csproj index e60491d..016221e 100644 --- a/testassets/SimpleRepo/src/Simple.Lib/Simple.Lib.csproj +++ b/testassets/SimpleRepo/src/Simple.Lib/Simple.Lib.csproj @@ -1,7 +1,5 @@ - - netstandard2.0;net461 diff --git a/testassets/SimpleRepo/build/common.props b/testassets/SimpleRepo/version.props similarity index 73% rename from testassets/SimpleRepo/build/common.props rename to testassets/SimpleRepo/version.props index 0e2b84e..a970297 100644 --- a/testassets/SimpleRepo/build/common.props +++ b/testassets/SimpleRepo/version.props @@ -1,6 +1,6 @@ - + 1.0.0 beta-$(BuildNumber) diff --git a/testassets/SimpleRepo/version.xml b/testassets/SimpleRepo/version.xml deleted file mode 100644 index fdf5de4..0000000 --- a/testassets/SimpleRepo/version.xml +++ /dev/null @@ -1,5 +0,0 @@ - - - dev - - diff --git a/tools/korebuild.schema.json b/tools/korebuild.schema.json new file mode 100644 index 0000000..9bf3a76 --- /dev/null +++ b/tools/korebuild.schema.json @@ -0,0 +1,21 @@ +{ + "title": "Config file for KoreBuild", + "$schema": "http://json-schema.org/draft-04/schema#", + "type": "object", + "properties": { + "toolsSource": { + "description": "The remote source used to download KoreBuild. Can be a file path.", + "type": "string", + "default": "https://aspnetcore.blob.core.windows.net/buildtools" + }, + "channel": { + "description": "The channel of KoreBuild used to select a version when korebuild-lock.txt is not present.", + "type": "string", + "default": "dev", + "enum": [ + "dev", + "rel/2.0.0" + ] + } + } +} diff --git a/version.xml b/version.props similarity index 100% rename from version.xml rename to version.props