Skip to content

Instantly share code, notes, and snippets.

@Artnoc1
Last active February 2, 2023 03:55
Show Gist options
  • Select an option

  • Save Artnoc1/69238e76bf7648de8f11a0dd9e4b06a4 to your computer and use it in GitHub Desktop.

Select an option

Save Artnoc1/69238e76bf7648de8f11a0dd9e4b06a4 to your computer and use it in GitHub Desktop.

Revisions

  1. Artnoc1 revised this gist Feb 2, 2023. 1 changed file with 0 additions and 15 deletions.
    15 changes: 0 additions & 15 deletions bash
    Original file line number Diff line number Diff line change
    @@ -1,21 +1,6 @@
    #!/usr/bin/env bash
    #
    # Pull in linux-stable updates to a kernel tree
    #
    # Copyright (C) 2017-2018 Nathan Chancellor
    #
    # This program is free software: you can redistribute it and/or modify
    # it under the terms of the GNU General Public License as published by
    # the Free Software Foundation, either version 3 of the License, or
    # (at your option) any later version.
    #
    # This program is distributed in the hope that it will be useful,
    # but WITHOUT ANY WARRANTY; without even the implied warranty of
    # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
    # GNU General Public License for more details.
    #
    # You should have received a copy of the GNU General Public License along with this program. If not, see <http://www.gnu.org/licenses/>


    # Colors for script
    BOLD="\033[1m"
  2. Artnoc1 revised this gist Feb 2, 2023. 1 changed file with 1 addition and 2 deletions.
    3 changes: 1 addition & 2 deletions bash
    Original file line number Diff line number Diff line change
    @@ -14,8 +14,7 @@
    # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
    # GNU General Public License for more details.
    #
    # You should have received a copy of the GNU General Public License
    # along with this program. If not, see <http://www.gnu.org/licenses/>
    # You should have received a copy of the GNU General Public License along with this program. If not, see <http://www.gnu.org/licenses/>


    # Colors for script
  3. Artnoc1 renamed this gist Feb 4, 2022. 1 changed file with 0 additions and 0 deletions.
    File renamed without changes.
  4. Artnoc1 renamed this gist Feb 4, 2022. 1 changed file with 0 additions and 0 deletions.
    File renamed without changes.
  5. Artnoc1 renamed this gist Sep 29, 2021. 1 changed file with 0 additions and 0 deletions.
    File renamed without changes.
  6. Artnoc1 created this gist Aug 29, 2021.
    262 changes: 262 additions & 0 deletions .bash.sh
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,262 @@
    #!/usr/bin/env bash
    #
    # Pull in linux-stable updates to a kernel tree
    #
    # Copyright (C) 2017-2018 Nathan Chancellor
    #
    # This program is free software: you can redistribute it and/or modify
    # it under the terms of the GNU General Public License as published by
    # the Free Software Foundation, either version 3 of the License, or
    # (at your option) any later version.
    #
    # This program is distributed in the hope that it will be useful,
    # but WITHOUT ANY WARRANTY; without even the implied warranty of
    # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
    # GNU General Public License for more details.
    #
    # You should have received a copy of the GNU General Public License
    # along with this program. If not, see <http://www.gnu.org/licenses/>


    # Colors for script
    BOLD="\033[1m"
    GRN="\033[01;32m"
    RED="\033[01;31m"
    RST="\033[0m"
    YLW="\033[01;33m"


    # Alias for echo to handle escape codes like colors
    function echo() {
    command echo -e "$@"
    }


    # Prints a formatted header to point out what is being done to the user
    function header() {
    if [[ -n ${2} ]]; then
    COLOR=${2}
    else
    COLOR=${RED}
    fi
    echo "${COLOR}"
    # shellcheck disable=SC2034
    echo "====$(for i in $(seq ${#1}); do echo "=\c"; done)===="
    echo "== ${1} =="
    # shellcheck disable=SC2034
    echo "====$(for i in $(seq ${#1}); do echo "=\c"; done)===="
    echo "${RST}"
    }


    # Prints an error in bold red
    function die() {
    echo
    echo "${RED}${1}${RST}"
    [[ ${2} = "-h" ]] && ${0} -h
    exit 1
    }


    # Prints a statement in bold green
    function success() {
    echo
    echo "${GRN}${1}${RST}"
    [[ -z ${2} ]] && echo
    }


    # Prints a warning in bold yellow
    function warn() {
    echo
    echo "${YLW}${1}${RST}"
    [[ -z ${2} ]] && echo
    }


    # Parse the provided parameters
    function parse_parameters() {
    while [[ $# -ge 1 ]]; do
    case ${1} in
    # Use git cherry-pick
    "-c"|"--cherry-pick")
    UPDATE_METHOD=cherry-pick ;;

    # Only update the linux-stable remote
    "-f"|"--fetch-only")
    FETCH_REMOTE_ONLY=true ;;

    # Help menu
    "-h"|"--help")
    echo
    echo "${BOLD}Command:${RST} ./$(basename "${0}") <options>"
    echo
    echo "${BOLD}Script description:${RST} Merges/cherry-picks Linux upstream into a kernel tree"
    echo
    echo "${BOLD}Required parameters:${RST}"
    echo " -c | --cherry-pick"
    echo " -m | --merge"
    echo " Call either git cherry-pick or git merge when updating from upstream"
    echo
    echo "${BOLD}Optional parameters:${RST}"
    echo " -f | --fetch-only"
    echo " Simply fetches the tags from linux-stable then exits"
    echo
    echo " -k | --kernel-folder"
    echo " The device's kernel source's location; this can either be a full path or relative to where the script is being executed."
    echo
    echo " -l | --latest"
    echo " Updates to the latest version available for the current kernel tree"
    echo
    echo " -p | --print-latest"
    echo " Prints the latest version available for the current kernel tree then exits"
    echo
    echo " -v | --version"
    echo " Updates to the specified version (e.g. -v 3.18.78)"
    echo
    echo "${BOLD}Defaults:${RST}"
    echo " If -l or -v are not specified, ONE version is picked at a time (e.g. 3.18.31 to 3.18.32)"
    echo
    echo " If -k is not specified, the script assumes it is in the kernel source folder already"
    echo
    exit 1 ;;

    # Kernel source location
    "-k"|"--kernel-folder")
    shift
    [[ $# -lt 1 ]] && die "Please specify a kernel source location!"

    KERNEL_FOLDER=${1} ;;

    # Update to the latest version upstream unconditionally
    "-l"|"--latest")
    UPDATE_MODE=1 ;;

    # Use git merge
    "-m"|"--merge")
    UPDATE_METHOD=merge ;;

    # Print the latest version from kernel.org
    "-p"|"--print-latest")
    PRINT_LATEST=true ;;

    # Update to the specified version
    "-v"|"--version")
    shift
    [[ $# -lt 1 ]] && die "Please specify a version to update!"

    TARGET_VERSION=${1} ;;

    *)
    die "Invalid parameter!" ;;
    esac

    shift
    done

    # If kernel source isn't specified, assume we're there
    [[ -z ${KERNEL_FOLDER} ]] && KERNEL_FOLDER=$(pwd)

    # Sanity checks
    [[ ! ${UPDATE_METHOD} ]] && die "Neither cherry-pick nor merge were specified, please supply one!" -h
    [[ ! -d ${KERNEL_FOLDER} ]] && die "Invalid kernel source location specified! Folder does not exist" -h
    [[ ! -f ${KERNEL_FOLDER}/Makefile ]] && die "Invalid kernel source location specified! No Makefile present" -h

    # Default update mode is one version at a time
    [[ -z ${UPDATE_MODE} && -z ${TARGET_VERSION} ]] && UPDATE_MODE=0
    }


    # Update the linux-stable remote (and add it if it doesn't exist)
    function update_remote() {
    header "Updating linux-stable"

    # Add remote if it isn't already present
    cd "${KERNEL_FOLDER}" || die "Could not change into ${KERNEL_FOLDER}!"

    if git fetch --tags https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable.git/; then
    success "linux-stable updated successfully!"
    else
    die "linux-stable update failed!"
    fi

    [[ ${FETCH_REMOTE_ONLY} ]] && exit 0
    }


    # Generate versions
    function generate_versions() {
    header "Calculating versions"

    # Full kernel version
    CURRENT_VERSION=$(make -s CC=gcc CROSS_COMPILE="" kernelversion)
    # First two numbers (3.4 | 3.10 | 3.18 | 4.4)
    CURRENT_MAJOR_VERSION=$(echo "${CURRENT_VERSION}" | cut -f 1,2 -d .)
    # Last number
    CURRENT_SUBLEVEL=$(echo "${CURRENT_VERSION}" | cut -d . -f 3)

    # Get latest update from upstream
    LATEST_VERSION=$(git tag --sort=-taggerdate -l "v${CURRENT_MAJOR_VERSION}"* | head -n 1 | sed s/v//)
    LATEST_SUBLEVEL=$(echo "${LATEST_VERSION}" | cut -d . -f 3)

    # Print the current/latest version and exit if requested
    echo "${BOLD}Current kernel version:${RST} ${CURRENT_VERSION}"
    echo
    echo "${BOLD}Latest kernel version:${RST} ${LATEST_VERSION}"
    if [[ ${PRINT_LATEST} ]]; then
    echo
    exit 0
    fi

    # UPDATE_MODES:
    # 0. Update one version
    # 1. Update to the latest version
    case ${UPDATE_MODE} in
    0)
    TARGET_SUBLEVEL=$((CURRENT_SUBLEVEL + 1))
    TARGET_VERSION=${CURRENT_MAJOR_VERSION}.${TARGET_SUBLEVEL} ;;
    1)
    TARGET_VERSION=${LATEST_VERSION} ;;
    esac

    # Make sure target version is between current version and latest version
    TARGET_SUBLEVEL=$(echo "${TARGET_VERSION}" | cut -d . -f 3)
    [[ ${TARGET_SUBLEVEL} -le ${CURRENT_SUBLEVEL} ]] && die "${TARGET_VERSION} is already present in ${CURRENT_VERSION}!"
    [[ ${TARGET_SUBLEVEL} -gt ${LATEST_SUBLEVEL} ]] && die "${CURRENT_VERSION} is the latest!"
    [[ ${CURRENT_SUBLEVEL} -eq 0 ]] && CURRENT_VERSION=${CURRENT_MAJOR_VERSION}

    RANGE=v${CURRENT_VERSION}..v${TARGET_VERSION}

    echo
    echo "${BOLD}Target kernel version:${RST} ${TARGET_VERSION}"
    echo
    }


    function update_to_target_version() {
    case ${UPDATE_METHOD} in
    "cherry-pick")
    if ! git cherry-pick "${RANGE}"; then
    die "Cherry-pick needs manual intervention! Resolve conflicts then run:
    git add . && git cherry-pick --continue"
    else
    header "${TARGET_VERSION} PICKED CLEANLY!" "${GRN}"
    fi ;;

    "merge")
    if ! GIT_MERGE_VERBOSITY=1 git merge --no-edit "v${TARGET_VERSION}"; then
    die "Merge needs manual intervention!
    Resolve conflicts then run git commit!"
    else
    header "${TARGET_VERSION} MERGED CLEANLY!" "${GRN}"
    fi ;;
    esac
    }


    parse_parameters "$@"
    update_remote
    generate_versions
    update_to_target_version