commit: bb12be00bf32ee33d45c8c0071f3603f60309a2d Author: Itai Ferber <itai <AT> itaiferber <DOT> net> AuthorDate: Sat Oct 12 17:30:59 2024 +0000 Commit: David Roman <davidroman96 <AT> gmail <DOT> com> CommitDate: Sun Oct 13 01:31:24 2024 +0000 URL: https://gitweb.gentoo.org/repo/proj/guru.git/commit/?id=bb12be00
app-eselect/eselect-swift: new package, add 1.0 Signed-off-by: Itai Ferber <itai <AT> itaiferber.net> app-eselect/eselect-swift/eselect-swift-1.0.ebuild | 24 ++ app-eselect/eselect-swift/files/swift-1.0.eselect | 274 +++++++++++++++++++++ app-eselect/eselect-swift/metadata.xml | 8 + 3 files changed, 306 insertions(+) diff --git a/app-eselect/eselect-swift/eselect-swift-1.0.ebuild b/app-eselect/eselect-swift/eselect-swift-1.0.ebuild new file mode 100644 index 000000000..c6b499b5c --- /dev/null +++ b/app-eselect/eselect-swift/eselect-swift-1.0.ebuild @@ -0,0 +1,24 @@ +# Copyright 1999-2024 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-${PV}.eselect" swift.eselect || die +} + +pkg_postinst() { + eselect swift update +} diff --git a/app-eselect/eselect-swift/files/swift-1.0.eselect b/app-eselect/eselect-swift/files/swift-1.0.eselect new file mode 100644 index 000000000..2679b553c --- /dev/null +++ b/app-eselect/eselect-swift/files/swift-1.0.eselect @@ -0,0 +1,274 @@ +# -*-eselect-*- vim: ft=eselect +# Copyright 2005-2024 Gentoo Authors +# Distributed under the terms of the GNU GPL version 2 or later + +DESCRIPTION="Manage the Swift symlink" +MAINTAINER="i...@itaiferber.net" +VERSION="1.0" + +inherit path-manipulation + +BIN_DIR="${EROOT%/}/usr/bin" + +### Utility Functions ### + +# @FUNCTION: get_index +# @USAGE: <element> <elements>... +# @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: <target identifier>... +# @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 &>/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: <target identifier> +# @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: <target identifier>... +# @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: <target identifier>... +# @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: <target identifier> +# @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: <target identifier> <target identifiers>... +# @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" +} + +do_show() { + local targets + mapfile -t targets < <(list_targets) + + if [[ -n "${targets[@]}" ]]; then + write_list_start "Current Swift implementation:" + local target="$(current_target "${targets[@]}")" + write_kv_list_entry "${target:-(unset)}" + else + write_list_start "No available Swift versions" + fi +} + +### Set Action ### + +describe_set() { + echo "Set active Swift version" +} + +describe_set_parameters() { + echo "<target>" +} + +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[@]}" +} diff --git a/app-eselect/eselect-swift/metadata.xml b/app-eselect/eselect-swift/metadata.xml new file mode 100644 index 000000000..564cdd4a2 --- /dev/null +++ b/app-eselect/eselect-swift/metadata.xml @@ -0,0 +1,8 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!DOCTYPE pkgmetadata SYSTEM "https://www.gentoo.org/dtd/metadata.dtd"> +<pkgmetadata> + <maintainer type="person"> + <email>i...@itaiferber.net</email> + <name>Itai Ferber</name> + </maintainer> +</pkgmetadata>