| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335 |
- #!/usr/bin/env bash
- set -euo pipefail
- #
- # variables
- #
- RESET="\033[0m"
- RED="\033[0;31m"
- YELLOW="\033[0;33m"
- MAGENTA="\033[0;95m"
- DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
- verbose=false
- update=false
- reinstall=false
- lockfile_path="$DIR/korebuild-lock.txt"
- config_file="$DIR/korebuild.json"
- channel='master'
- tools_source='https://aspnetcore.blob.core.windows.net/buildtools'
- target_os_name=''
- ci=false
- run_restore=''
- run_build=true
- run_pack=false
- run_tests=false
- build_all=false
- build_deps=true
- build_managed=''
- build_native=''
- build_nodejs=''
- build_java=''
- build_projects=''
- target_arch='x64'
- if [ "$(uname)" = "Darwin" ]; then
- target_os_name='osx'
- else
- target_os_name='linux'
- fi
- msbuild_args=()
- #
- # Functions
- #
- __usage() {
- echo "Usage: $(basename "${BASH_SOURCE[0]}") [options] [[--] <Arguments>...]
- Arguments:
- <Arguments>... Arguments passed to the command. Variable number of arguments allowed.
- Options:
- --arch The CPU architecture to build for (x64, arm, arm64). Default=$target_arch
- --os-name The base runtime identifier to build for (linux, osx, linux-musl). Default=$target_os_name
- --[no-]restore Run restore.
- --[no-]build Compile projects. (Implies --no-restore)
- --[no-]pack Produce packages.
- --[no-]test Run tests.
- --projects A list of projects to build. (Must be an absolute path.)
- Globbing patterns are supported, such as \"$(pwd)/**/*.csproj\".
- --no-build-deps Do not build project-to-project references and only build the specified project.
- --all Build all project types.
- --[no-]build-native Build native projects (C, C++).
- --[no-]build-managed Build managed projects (C#, F#, VB).
- --[no-]build-nodejs Build NodeJS projects (TypeScript, JS).
- --[no-]build-java Build Java projects.
- --ci Apply CI specific settings and environment variables.
- --verbose Show verbose output.
- Description:
- This build script installs required tools and runs an MSBuild command on this repository
- This script can be used to invoke various targets, such as targets to produce packages
- build projects, run tests, and generate code.
- "
- if [[ "${1:-}" != '--no-exit' ]]; then
- exit 2
- fi
- }
- get_korebuild() {
- local version
- if [ ! -f "$lockfile_path" ]; then
- __get_remote_file "$tools_source/korebuild/channels/$channel/latest.txt" "$lockfile_path"
- fi
- version="$(grep 'version:*' -m 1 "$lockfile_path")"
- if [[ "$version" == '' ]]; then
- __error "Failed to parse version from $lockfile_path. 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}error: $*${RESET}" 1>&2
- }
- __warn() {
- echo -e "${YELLOW}warning: $*${RESET}"
- }
- __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
- }
- #
- # main
- #
- while [[ $# -gt 0 ]]; do
- case $1 in
- -\?|-h|--help)
- __usage --no-exit
- exit 0
- ;;
- --arch)
- shift
- target_arch="${1:-}"
- [ -z "$target_arch" ] && __error "Missing value for parameter --arch" && __usage
- ;;
- --os-name)
- shift
- target_os_name="${1:-}"
- [ -z "$target_os_name" ] && __error "Missing value for parameter --os-name" && __usage
- ;;
- --restore|-[Rr]estore)
- run_restore=true
- ;;
- --no-restore)
- run_restore=false
- ;;
- --build|-[Bb]build)
- run_build=true
- ;;
- --no-build)
- run_build=false
- # --no-build implies --no-restore
- [ -z "$run_restore" ] && run_restore=false
- ;;
- --no-build-deps)
- build_deps=false
- ;;
- --pack|-[Pp]ack)
- run_pack=true
- ;;
- --no-pack)
- run_pack=false
- ;;
- --test|-[Tt]est)
- run_tests=true
- ;;
- --no-test)
- run_tests=false
- ;;
- --projects|-[Pp]rojects)
- shift
- build_projects="${1:-}"
- [ -z "$build_projects" ] && __error "Missing value for parameter --projects" && __usage
- ;;
- --all|-[Aa]ll)
- build_all=true
- ;;
- --build-managed|-BuildManaged)
- build_managed=true
- ;;
- --no-build-managed|-NoBuildManaged)
- build_managed=false
- ;;
- --build-nodejs|-BuildNodeJs)
- build_nodejs=true
- ;;
- --no-build-nodejs|-NoBuildNodeJs)
- build_nodejs=false
- ;;
- --build-java|-BuildJava)
- build_java=true
- ;;
- --no-build-java|-NoBuildJava)
- build_java=false
- ;;
- --build-native|-BuildNative)
- build_native=true
- ;;
- --no-build-native|-NoBuildNative)
- build_native=false
- ;;
- --ci|-[Cc][Ii])
- ci=true
- ;;
- --verbose|-[Vv]erbose)
- verbose=true
- ;;
- *)
- msbuild_args[${#msbuild_args[*]}]="$1"
- ;;
- 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
- 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
- __error "$config_file is invalid JSON. Its settings will be ignored."
- exit 1
- 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
- __error "$config_file is invalid JSON. Its settings will be ignored."
- exit 1
- fi
- else
- __error 'Missing required command: jq or python. Could not parse the JSON file. Its settings will be ignored.'
- exit 1
- fi
- [ ! -z "${config_channel:-}" ] && channel="$config_channel"
- [ ! -z "${config_tools_source:-}" ] && tools_source="$config_tools_source"
- fi
- export DOTNET_HOME="$DIR/.dotnet"
- get_korebuild
- if [ "$build_all" = true ]; then
- msbuild_args[${#msbuild_args[*]}]="-p:BuildAllProjects=true"
- elif [ ! -z "$build_projects" ]; then
- msbuild_args[${#msbuild_args[*]}]="-p:Projects=$build_projects"
- elif [ -z "$build_managed" ] && [ -z "$build_nodejs" ] && [ -z "$build_java" ] && [ -z "$build_native" ]; then
- # This goal of this is to pick a sensible default for `build.sh` with zero arguments.
- # We believe the most common thing our contributors will work on is C#, so if no other build group was picked, build the C# projects.
- __warn "No default group of projects was specified, so building the 'managed' subset of projects. Run ``build.sh -help`` for more details."
- build_managed=true
- fi
- if [ "$build_deps" = false ]; then
- msbuild_args[${#msbuild_args[*]}]="-p:BuildProjectReferences=false"
- fi
- # Only set these MSBuild properties if they were explicitly set by build parameters.
- [ ! -z "$build_java" ] && msbuild_args[${#msbuild_args[*]}]="-p:BuildJava=$build_java"
- [ ! -z "$build_native" ] && msbuild_args[${#msbuild_args[*]}]="-p:BuildNative=$build_native"
- [ ! -z "$build_nodejs" ] && msbuild_args[${#msbuild_args[*]}]="-p:BuildNodeJS=$build_nodejs"
- [ ! -z "$build_managed" ] && msbuild_args[${#msbuild_args[*]}]="-p:BuildManaged=$build_managed"
- # Run restore by default unless --no-restore or --no-build was specified.
- [ -z "$run_restore" ] && run_restore=true
- [ "$run_restore" = true ] && msbuild_args[${#msbuild_args[*]}]="-restore"
- msbuild_args[${#msbuild_args[*]}]="-p:_RunBuild=$run_build"
- msbuild_args[${#msbuild_args[*]}]="-p:_RunPack=$run_pack"
- msbuild_args[${#msbuild_args[*]}]="-p:_RunTests=$run_tests"
- msbuild_args[${#msbuild_args[*]}]="-p:TargetArchitecture=$target_arch"
- msbuild_args[${#msbuild_args[*]}]="-p:TargetOsName=$target_os_name"
- # Disable downloading ref assemblies as a tarball. Use netfx refs from the Microsoft.NETFramework.ReferenceAssemblies NuGet package instead.
- [ -z "${KOREBUILD_SKIP_INSTALL_NETFX:-}" ] && KOREBUILD_SKIP_INSTALL_NETFX=1
- export KOREBUILD_KEEPGLOBALJSON=1
- set_korebuildsettings "$tools_source" "$DOTNET_HOME" "$DIR" "$config_file" "$ci"
- # This incantation avoids unbound variable issues if msbuild_args is empty
- # https://stackoverflow.com/questions/7577052/bash-empty-array-expansion-with-set-u
- invoke_korebuild_command 'default-build' ${msbuild_args[@]+"${msbuild_args[@]}"}
|