diff --git a/hooks/debian/install-build-depends-prebuild b/hooks/debian/install-build-depends-prebuild new file mode 100755 index 0000000..f98c2a1 --- /dev/null +++ b/hooks/debian/install-build-depends-prebuild @@ -0,0 +1,8 @@ +#!/bin/bash + +source "${TAMARIN_UTIL}" + +if [ -f debian/control ]; then + info "Installing build dependencies..." + mk-build-deps --install debian/control +fi diff --git a/hooks/git/create-changelog-prebuild b/hooks/git/create-changelog-prebuild new file mode 100755 index 0000000..3fd2633 --- /dev/null +++ b/hooks/git/create-changelog-prebuild @@ -0,0 +1,43 @@ +#!/usr/bin/env bash + +source "${TAMARIN_UTIL}" + +if [ -f debian/changelog ] || [ ! -d .git ]; then + info "Not a Git repository or Debian changelog already exists !" + exit +fi + +if [ -z $(which git) ]; then + info "Installing Git..." + apt-get install --yes --no-install-recommends git-core +fi + +# Get commits log as changelog + +logs=$(git log --pretty=format:"%an - %h : %s" | sed 's/"/\\"/g') + +# Set the top commiter as the maintainer of the project if not defined +top_contributor=$(git log --pretty=short | git shortlog -s -n -e | sed 's/^\s*[0-9]*\s*//g' | head -n 1) +maintainer=$(get_opt maintainer "${top_contributor}") + +project_name=$(get_opt project_name) +version=$(get_opt version 0.0.0) +distribution=$(get_opt distribution UNRELEASED) +urgency=$(get_opt urgency low) + +commit_count=$(git rev-list --count --first-parent HEAD) +current_commit=$(git log -n 1 --pretty=format:"%h") +version_suffix=${commit_count}-${current_commit} + +echo "${project_name} (${version}) ${distribution}; urgency=${urgency}" > debian/changelog + +echo >> debian/changelog + +while read -r entry; do + echo " * ${entry}" >> debian/changelog +done <<< "$(echo -e "${logs}" | sed 's/^"//')" + +echo >> debian/changelog + +echo " -- ${maintainer} $(date -R)" >> debian/changelog +echo >> debian/changelog diff --git a/hooks/tamarin/export-dist-postbuild b/hooks/tamarin/export-dist-postbuild new file mode 100755 index 0000000..cd06a60 --- /dev/null +++ b/hooks/tamarin/export-dist-postbuild @@ -0,0 +1,10 @@ +#!/bin/bash + +# Create new directory +mkdir -p /dist + +# Move generated files +mv ../*.deb /dist +mv ../*.changes /dist +mv ../*.dsc /dist +mv ../*.tar.xz /dist diff --git a/lib/build.sh b/lib/build.sh index 70a20e0..caf9491 100755 --- a/lib/build.sh +++ b/lib/build.sh @@ -1,229 +1,61 @@ #!/usr/bin/env bash -#set -x +LIB_DIR=$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd ) +export TAMARIN_UTIL="${LIB_DIR}/util.sh" -DIR=$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd ) -source "${DIR}/util.sh" +source "${TAMARIN_UTIL}" DIST_DIR="${BASE_DIR}/dist" SRC_DIR="${BASE_DIR}/src" +HOOKS_DIR="${BASE_DIR}/hooks" -function get_project_opt { - filter=${1} - manifest_path=${SRC_DIR}/tamarin.json - if [ -e "${manifest_path}" ]; then - jq -r "${filter}" ${manifest_path} | sed 's/null//g' - fi -} +function exec_hooks { -function get_build_dir { - project_name="${1}" - temp_dir=$(mktemp -d) - build_dir="${temp_dir}/${project_name}" - mkdir -p "${build_dir}" - echo ${build_dir} -} + hook=${1} + workspace=${2} -function exec_hook { + hook_scripts=$( find "${HOOKS_DIR}" -type f -name "*${hook}" -executable) - hook_name=${1} - build_dir=${2} + for hook_script in ${hook_scripts}; do - hook_script="$(get_project_opt .hooks.${hook_name} | sed 's/null//')" + info "[hook-${hook}] Executing ${hook_script}" - # Test hook script existence - # if [ ! -f "${hook_script}" ]; then - # info "No ${hook_name} hook." - # return - # fi + ( cd "${workspace}" && "${hook_script}" ) - if [ -z "${hook_script}" ]; then - info "No ${hook_name} hook." - return - fi + # If the script did not execute properly, we stop here + if [ $? != 0 ]; then + fatal "The '${hook_script}' hook script did not finished properly !" + fi - info "Executing ${hook_name} hook..." + info "[hook-${hook}] ${hook_script} done." - # Ensure the hook script is executable - #chmod +x "${hook_script}" - - # Execute hook in a subshell - ( cd ${SRC_DIR} && DESTDIR="${build_dir}" SRCDIR="${SRC_DIR}" ${hook_script} ) - - # If the script did not execute properly, we stop here - if [ $? != 0 ]; then - fatal "The '${hook_name}' hook script did not finished properly !" - fi - -} - -function create_debian_control_file { - - debian_dir="${1}" - - control_file="${debian_dir}/control" - touch "${control_file}" - - package_name=$(get_project_opt .name) - echo "Package: ${package_name}" > "${control_file}" - - package_version=$(get_project_opt .version) - echo "Version: ${package_version:-0.0.0}" >> "${control_file}" - - package_section=$(get_project_opt .section) - echo "Section: ${package_section:-unknown}" >> "${control_file}" - - package_priority=$(get_project_opt .priority) - echo "Priority: ${package_priority:-optional}" >> "${control_file}" - - package_arch=$(get_project_opt .arch) - echo "Architecture: ${package_arch:-all}" >> "${control_file}" - - dependencies=$(get_project_opt ".dependencies | .[\"${DISTRIB}\"]") - - if [ ! -z "${dependencies}" ]; then - dependencies="" - for depKey in $(get_project_opt ".dependencies | .[\"${DISTRIB}\"] | keys | @sh"); do - depKey=$(echo ${depKey} | sed "s/^'\(.*\)'$/\1/"); - depValue=$(get_project_opt ".dependencies | .[\"${DISTRIB}\"] | .[\"${depKey}\"]" | sed "s/^'\(.*\)'$/\1/") - dependencies="${depKey} ($depValue), ${dependencies}" - done - fi - - dependencies=$(echo ${dependencies} | sed 's/,$//') - - debug "Package dependencies: ${dependencies:-None}" - - echo "Depends: ${dependencies}" >> "${control_file}" - - package_maintainer=$(get_project_opt .maintainer) - echo "Maintainer: ${package_maintainer:-Unknown}" >> "${control_file}" - - package_description=$(get_project_opt .description) - echo "Description: ${package_description:-No description}" >> "${control_file}" - -} - -function create_debian_hooks { - - debian_dir="${1}" - - pre_install="$(get_project_opt .hooks.preInstall)" - if [ ! -z "${pre_install}" ]; then - cp "${SRC_DIR}/${pre_install}" "${debian_dir}/preinst" - chmod +x "${debian_dir}/preinst" - fi - - post_install="$(get_project_opt .hooks.postInstall)" - if [ ! -z "${post_install}" ]; then - cp "${SRC_DIR}/${post_install}" "${debian_dir}/postinst" - chmod +x "${debian_dir}/postinst" - fi - - pre_remove="$(get_project_opt .hooks.preRemove)" - if [ ! -z "${pre_remove}" ]; then - cp "${SRC_DIR}/${pre_remove}" "${debian_dir}/prerm" - chmod +x "${debian_dir}/prerm" - fi - - post_remove="$(get_project_opt .hooks.postRemove)" - if [ ! -z "${post_remove}" ]; then - cp "${SRC_DIR}/${post_remove}" "${debian_dir}/postrm" - chmod +x "${debian_dir}/postrm" - fi - -} - -function create_debian_changelog { - - debian_dir="${1}" - changelog="${debian_dir}/changelog" - - logs="$(get_project_opt '.changelog' | sed 's/null//')" - logs="$(echo ${logs:-[]} | jq 'map(.+"\n") | add' | sed 's/null/No information/g')" - package_name=$(get_project_opt .name) - package_version=$(get_project_opt .version) - maintainer=$(get_project_opt .maintainer) - - echo "${package_name} (${package_version:-0.0.0}), ${DISTRIB}; urgency=low" > "${changelog}" - echo >> "${changelog}" - - while read -r entry; do - echo " * ${entry}" >> "${changelog}" - done <<< "$(echo -e "${logs}" | sed 's/^"//')" - - echo >> "${changelog}" - - echo "-- ${maintainer:-Unknown} $(date -R)" >> "${changelog}" - -} - -function create_debian_metadata { - - build_dir="${1}" - debian_dir="${build_dir}/DEBIAN" - - # Ensure debian dir exists - mkdir -p "${debian_dir}" - - create_debian_control_file "${debian_dir}" - create_debian_hooks "${debian_dir}" - create_debian_changelog "${debian_dir}" + done } function build_project { - info "Building project '${PROJECT_NAME}'..." + info "Building project ${PROJECT_NAME}..." - build_dir="$(get_build_dir '${PROJECT_NAME}')" + set_opt project_name "${PROJECT_NAME}" - debug "Build dir: ${build_dir}" - - # We don't generate Debian metadata files if a debian directory is present - if [ ! -d "${SRC_DIR}/debian" ]; then - info "No Debian directory detected in sources." - info "Generating Debian metadata files from Tamarin manifest..." - create_debian_metadata "${build_dir}" - else - info "A Debian directory is already present in sources." - fi - - exec_hook "prebuild" "${build_dir}" - - # Ensure $DIST_DIR exists - mkdir -p "${DIST_DIR}" + workspace=$(mktemp -d) + # Copy sources to workspace cd ${SRC_DIR} + cp -r ${SRC_DIR}/. "${workspace}" + + exec_hooks "prebuild" "${workspace}" + + cd "${workspace}" dpkg-buildpackage -us -uc if [ $? != 0 ]; then fatal "The build process has not completed successfuly !" fi - # Create new directory - mkdir -p "${DIST_DIR}/${PROJECT_NAME}/" - - # Move generated files - mv ../*.deb "${DIST_DIR}/${PROJECT_NAME}/" - mv ../*.changes "${DIST_DIR}/${PROJECT_NAME}/" - mv ../*.dsc "${DIST_DIR}/${PROJECT_NAME}/" - mv ../*.tar.xz "${DIST_DIR}/${PROJECT_NAME}/" - - exec_hook "postbuild" "${build_dir}" + exec_hooks "postbuild" "${workspace}" } -function main { - - manifest_path=${SRC_DIR}/tamarin.json - - if [ ! -f "${manifest_path}" ] && [ ! -d "${SRC_DIR}/debian" ]; then - fatal "There is no 'tamarin.json' nor debian packaging files in the project directory !" - fi - - build_project - -} - -main +build_project diff --git a/lib/hooks/git-prebuild.sh b/lib/hooks/git-prebuild.sh deleted file mode 100644 index a9bf588..0000000 --- a/lib/hooks/git-prebuild.sh +++ /dev/null @@ -1 +0,0 @@ -#!/bin/bash diff --git a/lib/util.sh b/lib/util.sh index 8310de4..3596a92 100644 --- a/lib/util.sh +++ b/lib/util.sh @@ -1,5 +1,7 @@ #!/usr/bin/env bash +OPT_FILE="/tmp/.tamarin_opts" + function info { echo "[${HOSTNAME}] [INFO] $@" } @@ -16,3 +18,19 @@ function fatal { echo "[${HOSTNAME}] [FATAL] $@" >&2 exit 1 } + +function get_opt { + opt_name=${1} + default_value=${2} + touch "${OPT_FILE}" + source "${OPT_FILE}" + echo ${!opt_name:-${default_value}} +} + +function set_opt { + opt_name=${1} + opt_value=${2} + touch "${OPT_FILE}" + sed -i "s/^${opt_name}*$//" "${OPT_FILE}" + echo "${opt_name}=\"${opt_value}\"" >> "${OPT_FILE}" +} diff --git a/package-project.sh b/package.sh similarity index 71% rename from package-project.sh rename to package.sh index fdf7644..679b9ef 100755 --- a/package-project.sh +++ b/package.sh @@ -2,8 +2,8 @@ set -e -DIR=$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd ) -source "$DIR/lib/util.sh" +TAMARIN_DIR=$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd ) +source "$TAMARIN_DIR/lib/util.sh" function show_usage { echo @@ -13,7 +13,7 @@ function show_usage { echo echo " - src Chemin vers le répertoire des sources du projet à empaqueter" echo " - dist Chemin vers le répertoire de destination du paquet à créer" - echo " - image Nom de l'image Docker à utiliser comme base pourl'environnement de build. Défaut: debian:jessie" + echo " - image Optionel - Nom de l'image Docker à utiliser comme base pourl'environnement de build. Défaut: debian:jessie" echo } @@ -27,8 +27,9 @@ function create_container { # Create temporary dir for the Dockerfile temp_dir="$(mktemp -d)" - # Link lib folder - ln -s $(readlink -f "$DIR/lib") "$temp_dir/lib" + # Link lib & hooks folders + ln -s $(readlink -f "$TAMARIN_DIR/lib") "$temp_dir/lib" + ln -s $(readlink -f "$TAMARIN_DIR/hooks") "$temp_dir/hooks" # Create Dockerfile cat << EOF > "$temp_dir/Dockerfile" @@ -37,15 +38,19 @@ function create_container { ENV DEBIAN_FRONTEND noninteractive RUN apt-get update &&\ - apt-get install --yes jq build-essential dh-make + apt-get install --yes build-essential devscripts - ADD ./lib /root/.tamarin - RUN chmod +x /root/.tamarin/build.sh + RUN mkdir /root/.tamarin + RUN mkdir /project + + ADD ./lib /root/.tamarin/lib + ADD ./hooks /hooks + RUN chmod +x /root/.tamarin/lib/build.sh VOLUME /src VOLUME /dist - CMD /root/.tamarin/build.sh + CMD /root/.tamarin/lib/build.sh EOF # Build image