#!/usr/bin/env bash

# MIT license (c) 2021 https://github.com/slowpeek
# Homepage: https://gist.github.com/slowpeek/beedb0c9c79638d4a7ec0099d0875ecb

# Simple apt sources generator for ubuntu.

############################ DEPRECATION NOTICE ############################
#
# This script has evolved into https://github.com/slowpeek/ubuntu-sources
#
############################################################################

set -eu

usage () {
    cat <<EOF
USAGE

    ubuntu-sources [options] distro [region]

'main' repo is always enabled. By default 'updates' and 'security'
updates channels are enabled.

Special region value 'mirror' can be used to leverage apt's built-in
'mirror://' protocol for mirror selection.

Special region value 'old' should be used with obsolete releases only
available at old-releases.ubuntu.com.


OPTIONS

--restricted --universe --multiverse
--no-restricted --no-universe --no-multiverse
    enable or disable the corresponding repo

--updates --security --backports --proposed
--no-updates --no-security --no-backports --no-proposed
    enable or disable the corresponding updates channel

--all
    enable 'restricted', 'universe', 'multiverse'

--src --no-src
    enable or disable (default) deb-src lines

--squeeze --no-squeeze
    enable or disable (default) squeezing repos into a single
    line. 'main' and 'restricted' (if enabled) always come together
    like in stock sources.list

Unknown options are ignored.

EXAMPLES

    ubuntu-sources hirsute
    ubuntu-sources bionic mirror
    ubuntu-sources --universe --no-updates --src bionic
    ubuntu-sources --all --no-multiverse --backports focal fr
    ubuntu-sources --all --squeeze precise old

EOF

    exit
}

apt_list () {
    echo deb "$url" "$distro" "$@"

    local channel
    for channel in updates security backports proposed; do
        [[ ${opt[$channel]} == n ]] ||
            echo deb "$url" "${distro}-${channel}" "$@"
    done

    echo
}

main () {
    local -A opt=(
        [src]=n [squeeze]=n
        [restricted]=n [universe]=n [multiverse]=n
        [updates]=y [security]=y [backports]=n [proposed]=n
    )

    local k
    while (($#)); do
        case $1 in
            --)
                shift
                break
                ;;

            --all)
                opt[restricted]=y
                opt[universe]=y
                opt[multiverse]=y
                ;;

            --no-*)
                k=${1:5}
                [[ -z ${opt[$k]-} ]] || opt[$k]=n
                ;;

            --*)
                k=${1:2}
                [[ -z ${opt[$k]-} ]] || opt[$k]=y
                ;;

            *)
                break
                ;;
        esac

        shift
    done

    (($#)) || usage

    local distro=$1 url

    case ${2-} in
        mirror)
            url=mirror://mirrors.ubuntu.com/mirrors.txt
            ;;
        old)
            url=http://old-releases.ubuntu.com/ubuntu/
            ;;
        *)
            url=http://${2:+$2.}archive.ubuntu.com/ubuntu/
            ;;
    esac

    local filter=(cat)
    # Generate deb-src lines if asked for.
    [[ ${opt[src]} == n ]] || filter=(sed -r 's/^deb (.+)/deb \1\ndeb-src \1/')

    {
        # Always collect 'main' and 'restricted' in a single line.
        local list=(main)
        [[ ${opt[restricted]} == n ]] || list+=(restricted)

        if [[ ${opt[squeeze]} == n ]]; then
            apt_list "${list[@]}"

            [[ ${opt[universe]} == n ]] || apt_list universe
            [[ ${opt[multiverse]} == n ]] || apt_list multiverse
        else
            [[ ${opt[universe]} == n ]] || list+=(universe)
            [[ ${opt[multiverse]} == n ]] || list+=(multiverse)

            apt_list "${list[@]}"
        fi
    } | "${filter[@]}"

}

[[ ! ${BASH_SOURCE[0]} == "$0" ]] || main "$@"