#!/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 SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" ## Load Functions ## source $SCRIPT_DIR/scripts/debian_build_lib.sh ## 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 fi parse_config_and_set_env_vars clean_or_create_build_dirs package_all generate_all create_source_tarball # Actually Build Package Files (cd ${PACKAGE_SOURCE_DIR}; debuild -us -uc) 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) export PACKAGE_NAME="$OPTARG" ;; v) export PACKAGE_VERSION="$OPTARG" ;; i) export INPUT_DIR="$OPTARG" ;; o) export 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 # Special Input Directories + Paths ABSOLUTE_PLACEMENT_DIR="${INPUT_DIR}/\$" PACKAGE_ROOT_PLACEMENT_DIR="${INPUT_DIR}/package_root" CONFIG="$INPUT_DIR/debian_config.json" 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 [[ -z "$INPUT_DIR" ]]; then echo "ERROR: -i Not Specified" ret=1 fi if [[ -z "$OUTPUT_DIR" ]]; then echo "ERROR: -o Not Specified." ret=1 fi if [[ ! -d "$PACKAGE_ROOT_PLACEMENT_DIR" ]]; then echo "ERROR: package_root directory does not exist" echo $PACKAGE_ROOT_PLACEMENT_DIR ret=1 fi if [[ ! -f "$CONFIG" ]]; then echo "ERROR: debian_config.json file does not exist" echo $CONFIG ret=1 fi return $ret } parse_config_and_set_env_vars(){ extract_base_cmd="python $SCRIPT_DIR/scripts/extract_json_value.py" # 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")" # Inputs INPUT_SAMPLES_DIR="$INPUT_DIR/samples" INPUT_DOCS_DIR="$INPUT_DIR/docs" DOCS_JSON_PATH="$INPUT_DIR/docs.json" PACKAGE_SOURCE_DIR="${OUTPUT_DIR}/${PACKAGE_NAME}-${PACKAGE_VERSION}" INSTALL_ROOT="/usr/share/${PACKAGE_NAME}" DEBIAN_DIR="${PACKAGE_SOURCE_DIR}/debian" DOCS_DIR="${PACKAGE_SOURCE_DIR}/docs" } clean_or_create_build_dirs(){ rm -rf ${PACKAGE_SOURCE_DIR} mkdir -p $DEBIAN_DIR } package_all(){ package_static_files package_package_root_placement package_absolute_placement package_samples package_docs } generate_all(){ generate_config_templates generate_manpages generate_manpage_manifest generate_sample_manifest write_debian_install_file } create_source_tarball(){ rm -f ${OUTPUT_DIR}/${PACKAGE_NAME}_${PACKAGE_VERSION}.orig.tar.gz tar -cvzf ${OUTPUT_DIR}/${PACKAGE_NAME}_${PACKAGE_VERSION}.orig.tar.gz -C $PACKAGE_SOURCE_DIR . } copy_files_to_output(){ # .deb, .dsc, etc.. Already in output dir # Copy Test files cp $SCRIPT_DIR/test/integration_tests/test_package.bats $OUTPUT_DIR } ## Packaging Functions ## package_static_files(){ cp -a $SCRIPT_DIR/package_files/debian/* ${PACKAGE_SOURCE_DIR}/debian } package_package_root_placement(){ add_dir_to_install ${PACKAGE_ROOT_PLACEMENT_DIR} "" } package_absolute_placement(){ if [[ -d "$ABSOLUTE_PLACEMENT_DIR" ]]; then abs_in_package_dir="\$" add_dir_to_install ${ABSOLUTE_PLACEMENT_DIR} $abs_in_package_dir # Get List of all files in directory tree, relative to ABSOLUTE_PLACEMENT_DIR abs_files=( $(_get_files_in_dir_tree $ABSOLUTE_PLACEMENT_DIR) ) # For each file add a a system placement for abs_file in ${abs_files[@]} do parent_dir=$(dirname $abs_file) filename=$(basename $abs_file) add_system_file_placement "$abs_in_package_dir/$abs_file" "/$parent_dir" done fi } package_samples(){ if [[ -d "$INPUT_SAMPLES_DIR" ]]; then cp -a $INPUT_SAMPLES_DIR/. $PACKAGE_SOURCE_DIR fi } package_docs(){ if [[ -d "$INPUT_DOCS_DIR" ]]; then mkdir -p $DOCS_DIR cp -a $INPUT_DOCS_DIR/. $DOCS_DIR fi } ## Generation Functions ## generate_config_templates(){ python ${SCRIPT_DIR}/scripts/config_template_generator.py $CONFIG $SCRIPT_DIR/templates/debian $DEBIAN_DIR $PACKAGE_VERSION } generate_manpages(){ if [[ -f "$DOCS_JSON_PATH" ]]; then mkdir -p $DOCS_DIR # Generate the manpages from json spec python ${SCRIPT_DIR}/scripts/manpage_generator.py ${DOCS_JSON_PATH} ${DOCS_DIR} fi } generate_manpage_manifest(){ # Get a list of files generated relative to $DOCS_DIR generated_manpages=( $(_get_files_in_dir_tree $DOCS_DIR) ) # Get path relative to $PACKAGE_SOURCE_DIR to prepend to each filename # This syntax is bash substring removal docs_rel_path=${DOCS_DIR#${PACKAGE_SOURCE_DIR}/} # Remove any existing manifest rm -f ${DEBIAN_DIR}/${PACKAGE_NAME}.manpages for manpage in ${generated_manpages[@]} do echo "${docs_rel_path}/${manpage}" >> "${DEBIAN_DIR}/${PACKAGE_NAME}.manpages" done } generate_sample_manifest(){ if [[ -d "$INPUT_SAMPLES_DIR" ]]; then generated_manpages=( $(_get_files_in_dir_tree $INPUT_SAMPLES_DIR) ) rm -f sample_manifest for sample in ${samples[@]} do echo "$sample" >> "${DEBIAN_DIR}/${PACKAGE_NAME}.examples" done else echo "Provide a 'samples' directory in INPUT_DIR to package samples" fi } execute "$@"