From 797e43654712f839e9a82b06666104d86d566609 Mon Sep 17 00:00:00 2001 From: Bryan Date: Wed, 6 Jan 2016 16:46:25 -0800 Subject: [PATCH] Package Tool Changes to support versioning changes. 1. Support CONFLICTS in debian packages 2. Associated Build Changes 3. Better cmd line option support in package_tool --- ..._config.json => dotnet-debian_config.json} | 10 +- .../debian/dotnet-nightly-debian_config.json | 54 +++++++++ packaging/debian/package_tool/README.md | 33 +++++- packaging/debian/package_tool/package_tool | 103 ++++++++++++++---- .../scripts/config_template_generator.py | 4 + .../package_tool/scripts/debian_build_lib.sh | 1 - .../package_tool/templates/debian/control | 1 + packaging/debian/package_tool/test.sh | 2 +- scripts/build/generate-version.ps1 | 20 ++-- scripts/build/generate-version.sh | 13 ++- scripts/package/package-debian.sh | 34 ++++-- 11 files changed, 218 insertions(+), 57 deletions(-) rename packaging/debian/{debian_config.json => dotnet-debian_config.json} (93%) create mode 100644 packaging/debian/dotnet-nightly-debian_config.json diff --git a/packaging/debian/debian_config.json b/packaging/debian/dotnet-debian_config.json similarity index 93% rename from packaging/debian/debian_config.json rename to packaging/debian/dotnet-debian_config.json index e27333547..caf938fee 100644 --- a/packaging/debian/debian_config.json +++ b/packaging/debian/dotnet-debian_config.json @@ -2,14 +2,14 @@ "maintainer_name":"Microsoft", "maintainer_email": "dotnetcore@microsoft.com", - "package_name": "dotnet-dev", + "package_name": "dotnet", "short_description": ".NET Core & command line tools", "long_description": ".NET Core is a cross-platform implementation of .NET Framework, a modern, modular platform\n for building diverse kinds of applications, from command-line applications to microservices and \n modern websites.\n This package contains the tools you will need to start writing applications for .NET Core. It includes \n compilers, package managers and other utilities that developers need.", "homepage": "https://dotnet.github.io/core", "release":{ - "package_version":"0.201", + "package_version":"0.0.0.0", "package_revision":"1", "urgency" : "low", "changelog_message" : "Bootstrap loop package" @@ -33,6 +33,10 @@ "libcurl3" : {} }, + "package_conflicts" : [ + "dotnet-nightly" + ], + "symlinks": { "bin/dotnet" : "usr/bin/dotnet", "bin/dotnet-build" : "usr/bin/dotnet-build", @@ -40,7 +44,7 @@ "bin/dotnet-compile-csc" : "usr/bin/dotnet-compile-csc", "bin/dotnet-compile-fsc" : "usr/bin/dotnet-compile-fsc", "bin/dotnet-compile-native" : "/usr/bin/dotnet-compile-native", - "bin/dotnet-init":"usr/bin/dotnet-new", + "bin/dotnet-new": "usr/bin/dotnet-new", "bin/dotnet-publish" : "usr/bin/dotnet-publish", "bin/dotnet-repl" : "usr/bin/dotnet-repl", "bin/dotnet-repl-csi" : "usr/bin/dotnet-repl-csi", diff --git a/packaging/debian/dotnet-nightly-debian_config.json b/packaging/debian/dotnet-nightly-debian_config.json new file mode 100644 index 000000000..f71a74193 --- /dev/null +++ b/packaging/debian/dotnet-nightly-debian_config.json @@ -0,0 +1,54 @@ +{ + "maintainer_name":"Microsoft", + "maintainer_email": "dotnetcore@microsoft.com", + + "package_name": "dotnet-nightly", + + "short_description": "Unstable Developer Build of .NET Core & command line tools", + "long_description": "Unstable Developer Build of .NET Core is a cross-platform implementation of .NET Framework, a modern, modular platform\n for building diverse kinds of applications, from command-line applications to microservices and \n modern websites.\n This package contains the tools you will need to start writing applications for .NET Core. It includes \n compilers, package managers and other utilities that developers need.", + "homepage": "https://dotnet.github.io/core", + + "release":{ + "package_version":"0.0.0.0", + "package_revision":"1", + "urgency" : "low", + "changelog_message" : "Bootstrap loop package" + }, + + "control": { + "priority":"standard", + "section":"devel", + "architecture":"any" + }, + + "copyright": "2015 Microsoft", + "license": { + "type": "MIT", + "full_text": "Copyright (c) 2015 Microsoft\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE." + }, + + "debian_dependencies":{ + "libssl-dev" : {}, + "clang-3.5" : {}, + "libcurl3" : {} + }, + + "package_conflicts" : [ + "dotnet" + ], + + "symlinks": { + "bin/dotnet" : "usr/bin/dotnet", + "bin/dotnet-compile" : "usr/bin/dotnet-compile", + "bin/dotnet-compile-csc" : "usr/bin/dotnet-compile-csc", + "bin/dotnet-compile-fsc" : "usr/bin/dotnet-compile-fsc", + "bin/dotnet-compile-native" : "/usr/bin/dotnet-compile-native", + "bin/dotnet-new": "usr/bin/dotnet-new", + "bin/dotnet-publish" : "usr/bin/dotnet-publish", + "bin/dotnet-repl" : "usr/bin/dotnet-repl", + "bin/dotnet-repl-csi" : "usr/bin/dotnet-repl-csi", + "bin/dotnet-restore" : "usr/bin/dotnet-restore", + "bin/dotnet-test" : "usr/bin/dotnet-test", + "bin/dotnet-resgen" : "usr/bin/dotnet-resgen" + } +} diff --git a/packaging/debian/package_tool/README.md b/packaging/debian/package_tool/README.md index c94686bb9..32b7443c0 100644 --- a/packaging/debian/package_tool/README.md +++ b/packaging/debian/package_tool/README.md @@ -1,13 +1,32 @@ -# Debian Packagify +# Debian Package Tool + +This is a tool which simplifies the creation process of a debian package. +Use of this tool requires creating a json configuration, and appropriate +directory structure with your desired files to be included. -A tool which consumes a directory structure to produce a debian package. ## Usage - package_tool [path to input directory] [path to output directory] +``` + Usage: package_tool [-i ] [-o ] + [-n ] [-v ] [-h] + + REQUIRED: + -i : Input directory conforming to package_tool conventions and debian_config.json + -o : Output directory for debian package and other artifacts + + OPTIONAL: + -n : name of created package, will override value in debian_config.json + -v : version of created package, will override value in debian_config.json + -h: Show this message + + NOTES: + See Below for more information on package_tool conventions and debian_config.json format +``` ## Input Directory Spec +``` package/ $/ (Contents in this directory will be placed absolutely according to their relative path) usr/lib/somelib.so (ex. This file gets placed at /usr/lib/somelib.so at install) @@ -17,12 +36,15 @@ A tool which consumes a directory structure to produce a debian package. debian_config.json (See example below) docs.json (For manpage generation) (ex. dotnet-commands-test.sh) +``` +Note: The default install root is `/usr/share/{package_name}` where package_name is replaced with the name of the created package ## full example debian_config.json -Note: remove all comments before using this +Note: Use the commentless version here (https://github.com/dotnet/cli/blob/master/packaging/debian/package_tool/example_config.json) +```json { "maintainer_name":"Microsoft", // [required] "maintainer_email": "optimus@service.microsoft.com", // [required] @@ -61,4 +83,5 @@ Note: remove all comments before using this "symlinks": { // (optional no defaults) "path_relative_to_package_root/test_exe.sh" : "usr/bin/test_exe.sh" } - } \ No newline at end of file + } +``` \ No newline at end of file diff --git a/packaging/debian/package_tool/package_tool b/packaging/debian/package_tool/package_tool index 044530e38..b27a4681e 100755 --- a/packaging/debian/package_tool/package_tool +++ b/packaging/debian/package_tool/package_tool @@ -16,22 +16,12 @@ SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" ## Load Functions ## source $SCRIPT_DIR/scripts/debian_build_lib.sh -INPUT_DIR="$1" -OUTPUT_DIR="$2" -INPUT_PACKAGE_VERSION="$3" - -# Special Input Directories + Paths -ABSOLUTE_PLACEMENT_DIR="${INPUT_DIR}/\$" -PACKAGE_ROOT_PLACEMENT_DIR="${INPUT_DIR}/package_root" - -# Inputs -INPUT_SAMPLES_DIR="$INPUT_DIR/samples" -INPUT_DOCS_DIR="$INPUT_DIR/docs" -DOCS_JSON_PATH="$INPUT_DIR/docs.json" -CONFIG="$INPUT_DIR/debian_config.json" - ## Debian Package Creation Functions ## execute(){ + if ! parse_args_and_set_env_vars $@; then + exit 1 + fi + # Exit if required validation fails if ! validate_inputs; then exit 1 @@ -49,6 +39,60 @@ execute(){ copy_files_to_output } +parse_args_and_set_env_vars(){ + OPTIND=1 # Reset in case getopts has been used previously in the shell. + + while getopts ":n:v:i:o:h" opt; do + case $opt in + n) + PACKAGE_NAME="$OPTARG" + ;; + v) + PACKAGE_VERSION="$OPTARG" + ;; + i) + INPUT_DIR="$OPTARG" + ;; + o) + OUTPUT_DIR="$OPTARG" + ;; + h) + print_help + return 1 + ;; + \?) + echo "Invalid option: -$OPTARG" >&2 + return 1 + ;; + :) + echo "Option -$OPTARG requires an argument." >&2 + return 1 + ;; + esac + done + + return 0 +} + +print_help(){ + echo "Usage: package_tool [-i ] [-o ] + [-n ] [-v ] [-h] + + REQUIRED: + -i : Input directory conforming to package_tool conventions and debian_config.json + -o : Output directory for debian package and other artifacts + + OPTIONAL: + -n : name of created package, will override value in debian_config.json + -v : version of created package, will override value in debian_config.json + -h: Show this message + + NOTES: + See Readme for more information on package_tool conventions and debian_config.json format + https://github.com/dotnet/cli/tree/master/packaging/debian/package_tool + " +} + validate_inputs(){ local ret=0 if [[ ! -d $ABSOLUTE_PLACEMENT_DIR ]]; then @@ -69,20 +113,35 @@ validate_inputs(){ ret=1 fi + if [[ -z "$INPUT_DIR" ]]; + echo "ERROR: -i Not Specified" + ret=1 + fi + + if [[ -z "$OUTPUT_DIR" ]]; + echo "ERROR: -o Not Specified." + ret=1 + fi + return $ret } parse_config_and_set_env_vars(){ extract_base_cmd="python $SCRIPT_DIR/scripts/extract_json_value.py" - - PACKAGE_NAME=$($extract_base_cmd $CONFIG "package_name") - # Override JSON Defined Version w/ Cmd Line ARG - if [ -z $INPUT_PACKAGE_VERSION ]; then - PACKAGE_VERSION=$($extract_base_cmd $CONFIG "release.package_version") - else - PACKAGE_VERSION=$INPUT_PACKAGE_VERSION - fi + # Arguments Take Precedence over Config + [ -z "$PACKAGE_VERSION" ] && PACKAGE_VERSION="$($extract_base_cmd $CONFIG "release.package_version")" + [ -z "$PACKAGE_NAME" ] && PACKAGE_NAME="$($extract_base_cmd $CONFIG "package_name")" + + # Special Input Directories + Paths + ABSOLUTE_PLACEMENT_DIR="${INPUT_DIR}/\$" + PACKAGE_ROOT_PLACEMENT_DIR="${INPUT_DIR}/package_root" + + # Inputs + INPUT_SAMPLES_DIR="$INPUT_DIR/samples" + INPUT_DOCS_DIR="$INPUT_DIR/docs" + DOCS_JSON_PATH="$INPUT_DIR/docs.json" + CONFIG="$INPUT_DIR/debian_config.json" PACKAGE_SOURCE_DIR="${OUTPUT_DIR}/${PACKAGE_NAME}-${PACKAGE_VERSION}" INSTALL_ROOT="/usr/share/${PACKAGE_NAME}" diff --git a/packaging/debian/package_tool/scripts/config_template_generator.py b/packaging/debian/package_tool/scripts/config_template_generator.py index 9c62ab1af..12becc6c5 100755 --- a/packaging/debian/package_tool/scripts/config_template_generator.py +++ b/packaging/debian/package_tool/scripts/config_template_generator.py @@ -86,6 +86,9 @@ def generate_control(config_data, template_dir): dependency_data = config_data.get("debian_dependencies", None) dependency_str = get_dependendent_packages_string(dependency_data) + conflict_data = config_data.get("package_conflicts", []) + conflict_str = ', '.join(conflict_data) + # Default to empty dict, so we don't explode on nested optional values control_data = config_data.get("control", dict()) @@ -99,6 +102,7 @@ def generate_control(config_data, template_dir): ARCH=control_data.get("architecture", "all"), DEPENDENT_PACKAGES=dependency_str, + CONFLICT_PACKAGES=conflict_str, PACKAGE_NAME=config_data["package_name"], MAINTAINER_NAME=config_data["maintainer_name"], diff --git a/packaging/debian/package_tool/scripts/debian_build_lib.sh b/packaging/debian/package_tool/scripts/debian_build_lib.sh index c899928cf..0b3f4141d 100755 --- a/packaging/debian/package_tool/scripts/debian_build_lib.sh +++ b/packaging/debian/package_tool/scripts/debian_build_lib.sh @@ -14,7 +14,6 @@ # Summary: Writes the contents of the "install_placement" array to the debian/install # This array is populated by calls to the "add_system_file_placement" function # Usage: write_debian_install_file - write_debian_install_file(){ # Remove any existing install file, we need to overwrite it rm -f ${PACKAGE_SOURCE_DIR}/debian/install diff --git a/packaging/debian/package_tool/templates/debian/control b/packaging/debian/package_tool/templates/debian/control index e84255059..49fb2b994 100644 --- a/packaging/debian/package_tool/templates/debian/control +++ b/packaging/debian/package_tool/templates/debian/control @@ -14,5 +14,6 @@ Homepage: {HOMEPAGE} Package: {PACKAGE_NAME} Architecture: {ARCH} Depends: ${{shlibs:Depends}}, ${{misc:Depends}}{DEPENDENT_PACKAGES} +Conflicts: {CONFLICT_PACKAGES} Description: {SHORT_DESCRIPTION} {LONG_DESCRIPTION} diff --git a/packaging/debian/package_tool/test.sh b/packaging/debian/package_tool/test.sh index 739e1feb3..9a7e2fd69 100755 --- a/packaging/debian/package_tool/test.sh +++ b/packaging/debian/package_tool/test.sh @@ -24,7 +24,7 @@ run_integration_tests(){ mkdir -p $output_dir # Build the actual package - $DIR/package_tool $input_dir $output_dir + $DIR/package_tool -i $input_dir -o $output_dir # Integration Test Entrypoint placed by package_tool bats $output_dir/test_package.bats diff --git a/scripts/build/generate-version.ps1 b/scripts/build/generate-version.ps1 index b36e40640..26725d480 100644 --- a/scripts/build/generate-version.ps1 +++ b/scripts/build/generate-version.ps1 @@ -3,17 +3,15 @@ # Licensed under the MIT license. See LICENSE file in the project root for full license information. # -#. "$PSScriptRoot\..\common\_common.ps1" +$ReleaseSuffix = "dev" +$MajorVersion = 1 +$MinorVersion = 0 +$PatchVersion = 0 -# Get the timestamp of the most recent commit -$timestamp = git log -1 --format=%ct -$commitTime = [timespan]::FromSeconds($timestamp) +#TODO @krwq is working on this +$CommitCountVersion = 0 -$majorVersion = 1 -$minorVersion = 0 -$buildnumber = 0 -$revnumber = $commitTime.TotalSeconds +# Zero Padded Suffix for use with Nuget +$VersionSuffix = "$ReleaseSuffix-{0:D6}" -f $CommitCountVersion -$VersionSuffix = "dev-$revnumber" - -$env:DOTNET_BUILD_VERSION = "$majorVersion.$minorVersion.$buildnumber.$revnumber" \ No newline at end of file +$env:DOTNET_BUILD_VERSION = "$MajorVersion.$MinorVersion.$PatchVersion.$CommitCountVersion" \ No newline at end of file diff --git a/scripts/build/generate-version.sh b/scripts/build/generate-version.sh index 6d6f168b3..1a3894d83 100755 --- a/scripts/build/generate-version.sh +++ b/scripts/build/generate-version.sh @@ -4,9 +4,12 @@ # Licensed under the MIT license. See LICENSE file in the project root for full license information. # -# UTC Timestamp of the last commit is used as the build number. This is for easy synchronization of build number between Windows, OSX and Linux builds. -LAST_COMMIT_TIMESTAMP=$(git log -1 --format=%ct) -export DOTNET_BUILD_VERSION=1.0.0-dev-$LAST_COMMIT_TIMESTAMP -echo "Version: $DOTNET_BUILD_VERSION" +export RELEASE_SUFFIX=dev +export MAJOR_VERSION=1 +export MINOR_VERSION=0 +export PATCH_VERSION=0 -unset LAST_COMMIT_TIMESTAMP +#TODO @krwq is working on this +export COMMIT_COUNT_VERSION=0 + +export DOTNET_BUILD_VERSION=$MAJOR_VERSION.$MINOR_VERSION.$PATCH_VERSION.$COMMIT_COUNT_VERSION diff --git a/scripts/package/package-debian.sh b/scripts/package/package-debian.sh index 89c81d3e2..0804d7060 100755 --- a/scripts/package/package-debian.sh +++ b/scripts/package/package-debian.sh @@ -18,12 +18,12 @@ DIR="$( cd -P "$( dirname "$SOURCE" )" && pwd )" source "$DIR/../common/_common.sh" -if [ "$UNAME" != "Linux" ]; then - error "Debian Package build only supported on Linux" +if [ "$OSNAME" != "ubuntu" ]; then + error "Debian Package build only supported on Ubuntu" exit 1 fi -PACKAGING_ROOT=$REPOROOT/packaging/debian +PACKAGING_ROOT="$REPOROOT/packaging/debian" OUTPUT_DIR="$REPOROOT/artifacts" PACKAGE_LAYOUT_DIR="$OUTPUT_DIR/deb_intermediate" @@ -32,12 +32,28 @@ TEST_STAGE_DIR="$PACKAGE_OUTPUT_DIR/test" REPO_BINARIES_DIR="$REPOROOT/artifacts/ubuntu.14.04-x64/stage2" MANPAGE_DIR="$REPOROOT/Documentation/manpages" +NIGHTLY_PACKAGE_NAME="dotnet-nightly" +RELEASE_PACKAGE_NAME="dotnet" + execute_build(){ + determine_package_name create_empty_debian_layout copy_files_to_debian_layout create_debian_package } +determine_package_name(){ + if [[ "$RELEASE_SUFFIX" == "dev" ]]; then + DOTNET_DEB_PACKAGE_NAME=$NIGHTLY_PACKAGE_NAME + elif [[ "beta rc1 rc2 rtm" =~ (^| )"$RELEASE_SUFFIX"($| ) ]]; then + DOTNET_DEB_PACKAGE_NAME=$RELEASE_PACKAGE_NAME + elif [[ "$RELEASE_SUFFIX" == "" ]]; then + DOTNET_DEB_PACKAGE_NAME=$RELEASE_PACKAGE_NAME + else + DOTNET_DEB_PACKAGE_NAME=$NIGHTLY_PACKAGE_NAME + fi +} + execute_test(){ test_debian_package } @@ -45,8 +61,8 @@ execute_test(){ create_empty_debian_layout(){ header "Creating empty debian package layout" - rm -rf $PACKAGE_LAYOUT_DIR - mkdir -p $PACKAGE_LAYOUT_DIR + rm -rf "$PACKAGE_LAYOUT_DIR" + mkdir -p "$PACKAGE_LAYOUT_DIR" mkdir "$PACKAGE_LAYOUT_DIR/\$" mkdir "$PACKAGE_LAYOUT_DIR/package_root" @@ -61,7 +77,7 @@ copy_files_to_debian_layout(){ cp -a "$REPO_BINARIES_DIR/." "$PACKAGE_LAYOUT_DIR/package_root" # Copy config file - cp "$PACKAGING_ROOT/debian_config.json" "$PACKAGE_LAYOUT_DIR" + cp "$PACKAGING_ROOT/$DOTNET_DEB_PACKAGE_NAME-debian_config.json" "$PACKAGE_LAYOUT_DIR/debian_config.json" # Copy Manpages cp -a "$MANPAGE_DIR/." "$PACKAGE_LAYOUT_DIR/docs" @@ -70,9 +86,9 @@ copy_files_to_debian_layout(){ create_debian_package(){ header "Packing .deb" - mkdir -p $PACKAGE_OUTPUT_DIR + mkdir -p "$PACKAGE_OUTPUT_DIR" - $PACKAGING_ROOT/package_tool/package_tool $PACKAGE_LAYOUT_DIR $PACKAGE_OUTPUT_DIR $DOTNET_BUILD_VERSION + "$PACKAGING_ROOT/package_tool/package_tool" -i "$PACKAGE_LAYOUT_DIR" -o "$PACKAGE_OUTPUT_DIR" -v $DOTNET_BUILD_VERSION -n $DOTNET_DEB_PACKAGE_NAME } test_debian_package(){ @@ -85,7 +101,7 @@ test_debian_package(){ # E2E Testing of package surface area # Disabled: https://github.com/dotnet/cli/issues/381 - #run_e2e_test + # run_e2e_test } run_e2e_test(){