From 92283709ccd542dced357da54389ae312c399a49 Mon Sep 17 00:00:00 2001 From: Itai Ferber Date: Tue, 25 Mar 2025 20:28:54 -0400 Subject: [PATCH] app-eselect/eselect-swift: add 1.0-r1 Adds support for 'show --latest' to get the latest available version of Swift on the system. Signed-off-by: Itai Ferber --- .../eselect-swift/eselect-swift-1.0-r1.ebuild | 24 ++ .../eselect-swift/files/swift-1.0-r1.eselect | 289 ++++++++++++++++++ 2 files changed, 313 insertions(+) create mode 100644 app-eselect/eselect-swift/eselect-swift-1.0-r1.ebuild create mode 100644 app-eselect/eselect-swift/files/swift-1.0-r1.eselect diff --git a/app-eselect/eselect-swift/eselect-swift-1.0-r1.ebuild b/app-eselect/eselect-swift/eselect-swift-1.0-r1.ebuild new file mode 100644 index 0000000000..49ee44ece7 --- /dev/null +++ b/app-eselect/eselect-swift/eselect-swift-1.0-r1.ebuild @@ -0,0 +1,24 @@ +# Copyright 1999-2025 Gentoo Authors +# Distributed under the terms of the GNU General Public License v2 + +EAPI=8 + +DESCRIPTION="Manages Swift symlinks" +HOMEPAGE="https://wiki.gentoo.org/wiki/No_homepage" + +S="${WORKDIR}" + +LICENSE="GPL-2" +SLOT="0" +KEYWORDS="~amd64" + +RDEPEND="app-admin/eselect" + +src_install() { + insinto /usr/share/eselect/modules + newins "${FILESDIR}/swift-${PVR}.eselect" swift.eselect || die +} + +pkg_postinst() { + eselect swift update +} diff --git a/app-eselect/eselect-swift/files/swift-1.0-r1.eselect b/app-eselect/eselect-swift/files/swift-1.0-r1.eselect new file mode 100644 index 0000000000..77a587915b --- /dev/null +++ b/app-eselect/eselect-swift/files/swift-1.0-r1.eselect @@ -0,0 +1,289 @@ +# -*-eselect-*- vim: ft=eselect +# Copyright 2005-2025 Gentoo Authors +# Distributed under the terms of the GNU GPL version 2 or later + +DESCRIPTION="Manage the Swift symlink" +MAINTAINER="itai@itaiferber.net" +VERSION="1.0" + +inherit path-manipulation + +BIN_DIR="${EROOT%/}/usr/bin" + +### Utility Functions ### + +# @FUNCTION: get_index +# @USAGE: ... +# @DESCRIPTION: +# Returns the index of an element in an array, or the empty string if the +# element was not found. +get_index() { + local element="$1" + shift + local i elements=( "$@" ) + for i in "${!elements[@]}"; do + if [[ "${elements[i]}" = "${element}" ]]; then + echo "${i}" + return 0 + fi + done + return 1 +} + +# @FUNCTION: sort_swift_targets +# @USAGE: ... +# @DESCRIPTION: +# Lexicographically sorts an array of Swift target identifiers. +sort_swift_targets() { + # `sort` may not support '--version-sort', so fall back on error + local vsort="sort --version-sort" + ${vsort} /dev/null || vsort="sort" + + # Stolen from `app-eselect/eselect-luajit`: to handle potential `_beta` + # version suffixes, we: + # 1. Turn `swift-x.y.z` into `x.y.z 1 swift-x.y.z` + # 2. Turn `swift-x.y.z_beta...` into `x.y.z 0 swift-x.y.z_beta...` + # 3. Sort, which moves `_beta` versions before corresponding non-beta + # versions + # 4. Remove leading trivia + printf "%s\n" "$@" \ + | sed -e 's/^\(swift-\)\?\([[:digit:].]\+\)[-_]beta/\2 0 &/' \ + -e 't;s/^\(swift-\)\?\([[:digit:].]\+\)/\2 1 &/' \ + | LC_ALL=C ${vsort} \ + | sed 's/.* //' +} + +# @FUNCTION: list_targets +# @DESCRIPTION: +# Returns a lexicographically-sorted list of Swift targets found in `BIN_DIR`. +list_targets() { + local identifiers + mapfile -t identifiers < <(find "${BIN_DIR}" -maxdepth 1 -type l -iname 'swift-[[:digit:]]*' -exec basename '{}' ';') + sort_swift_targets "${identifiers[@]}" +} + +# @FUNCTION: list_target_links +# @USAGE: +# @DESCRIPTION: +# Given a Swift target identifier, lists all of the symlinks found in `BIN_DIR` +# that correspond to that Swift target. +list_target_links() { + local target="$1" + local version_number="${target#swift-}" + local swift_dir="$(dirname "$(canonicalise "${BIN_DIR}/${target}")")" + + local files + mapfile -t files < <(find "${BIN_DIR}" -maxdepth 1 -type l -iname "*-${version_number}") + for f in "${files[@]}"; do + local d="$(dirname "$(canonicalise "${f}")")" + if [[ "${d}" == "${swift_dir}"* ]]; then + echo "${f}" + fi + done +} + +# @FUNCTION: current_target_index +# @USAGE: ... +# @DESCRIPTION: +# Returns the index of the currently-set target from the given list of available +# Swift targets. If `/usr/bin/swift` does not point to any of the given Swift +# targets, returns an empty string. +current_target_index() { + local t canonical_targets=() + for t in "$@"; do + canonical_targets+=("$(canonicalise "${BIN_DIR}/${t}")") + done + + local canonical_swift_path="$(canonicalise "${BIN_DIR}/swift")" + get_index "${canonical_swift_path}" "${canonical_targets[@]}" +} + +# @FUNCTION: current_target +# @USAGE: ... +# @DESCRIPTION: +# Returns the target identifier of the currently-set target from the given list +# of available Swift targets. If `/usr/bin/swift` does not point to any of the +# given Swift targets, returns an empty string. +current_target() { + local targets=( "$@" ) + local target="$(current_target_index "${targets[@]}")" + if is_number "${target}"; then + echo "${targets[target]}" + else + return 1 + fi +} + +# @FUNCTION: unset_target +# @USAGE: +# @DESCRIPTION: +# Unsets any unversioned links in `BIN_DIR` if they point to the given Swift +# target identifier. +unset_target() { + local target="$1" + local version_number="${target#swift-}" + + local links + mapfile -t links < <(list_target_links "${target}") + + local link + for link in "${links[@]}"; do + local unversioned_link="${link%-"${version_number}"}" + if [[ "$(canonicalise "${link}")" = "$(canonicalise "${unversioned_link}")" ]]; then + rm "${unversioned_link}" || die -q "Couldn't remove symlink '${unversioned_link}'" + fi + done +} + +# @FUNCTION: set_target +# @USAGE: ... +# @DESCRIPTION: +# Unsets the current Swift target and sets unversioned symlinks in `BIN_DIR` for +# the given Swift target identifier. Does nothing if the given target identifier +# is the same as the current target identifier. +set_target() { + local target="$1" + shift + local current_target="$(current_target "$@")" + if [[ "${target}" = "${current_target}" ]]; then + return + fi + + unset_target "${current_target}" + + local version_number="${target#swift-}" + local links + mapfile -t links < <(list_target_links "${target}") + + local link + for link in "${links[@]}"; do + local unversioned_link="${link%-"${version_number}"}" + ln -fs "${link}" "${unversioned_link}" || die -q "Couldn't create symlink '${unversioned_link}'" + done +} + +### List Action ### + +describe_list() { + echo "Lists available Swift versions" +} + +do_list() { + local targets + mapfile -t targets < <(list_targets) + if [[ -n "${targets}" ]]; then + local current_target="$(current_target_index "${targets[@]}")" + + if is_number "${current_target}"; then + targets[current_target]="$(highlight_marker "${targets[current_target]}")" + fi + + write_list_start "Available Swift versions:" + write_numbered_list "${targets[@]}" + else + write_list_start "No available Swift versions" + fi +} + +### Show Action ### + +describe_show() { + echo "Show the current Swift implementation" +} + +describe_show_options() { + echo "--latest : Show the latest available Swift implementation" +} + +do_show() { + local show_latest=false + if [[ $# -gt 0 && "$1" = "--latest" ]]; then + show_latest=true + shift + fi + + [[ $# -eq 0 ]] || die "'show' takes only '--latest' as a parameter" + + local targets + mapfile -t targets < <(list_targets) + + if [[ -z "${targets[@]}" ]]; then + write_list_start "No available Swift versions" + elif [[ "${show_latest}" = 'true' ]]; then + write_list_start "Latest Swift implementation:" + write_kv_list_entry "${targets[-1]}" + else + write_list_start "Current Swift implementation:" + local target="$(current_target "${targets[@]}")" + write_kv_list_entry "${target:-(unset)}" + fi +} + +### Set Action ### + +describe_set() { + echo "Set active Swift version" +} + +describe_set_parameters() { + echo "" +} + +describe_set_options() { + echo "target : Target number or name (from 'list')" +} + +do_set() { + [[ $# -eq 0 || -z "$1" ]] && die -q "No Swift version specified" + [[ $# -gt 1 ]] && die -q "'set' takes only one parameter" + + local targets + mapfile -t targets < <(list_targets) + + local target="$1" + if is_number "${target}"; then + [[ "$target" -gt 0 && "$1" -le "${#targets[@]}" ]] || die -q "'$1' is not a valid target" + target="${targets[target-1]}" + else + target_index="$(get_index "$1" "${targets[@]}")" + is_number "${target_index}" || die -q "'$1' is not a valid target" + fi + + set_target "${target}" "${targets[@]}" +} + +### Unset Action ### + +describe_unset() { + echo "Unsets any active Swift version" +} + +do_unset() { + [[ $# -eq 0 ]] || die -q "'unset' does not take any parameters" + local targets + mapfile -t targets < <(list_targets) + local target="$(current_target "${targets[@]}")" + unset_target "${target}" +} + +### Update Action ### + +describe_update() { + echo "Switch to the most recent Swift version" +} + +do_update() { + [[ $# -eq 0 ]] || die -q "'update' does not take any parameters" + + local targets + mapfile -t targets < <(list_targets) + [[ "${#targets[@]}" -gt 0 ]] || die -q "No Swift versions found" + + local target="$(current_target "${targets[@]}")" + if [[ -n "${target}" ]]; then + unset_target "${target}" + fi + + local new_target="${targets[-1]}" + set_target "${new_target}" "${targets[@]}" +}