aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorIonen Wolkens <ionen@gentoo.org>2022-11-15 21:50:14 -0500
committerIonen Wolkens <ionen@gentoo.org>2022-11-16 09:26:09 -0500
commitcd681b82edf58452e185dba64ddab2a0870884da (patch)
tree5a0f979acaa4c38c2965b3170cd5bcd796a15794
parentv1.2.3 (diff)
downloadeselect-wine-cd681b82edf58452e185dba64ddab2a0870884da.tar.gz
eselect-wine-cd681b82edf58452e185dba64ddab2a0870884da.tar.bz2
eselect-wine-cd681b82edf58452e185dba64ddab2a0870884da.zip
wine.eselect: rewrite initial import
Signed-off-by: Ionen Wolkens <ionen@gentoo.org>
-rw-r--r--wine.eselect1167
1 files changed, 323 insertions, 844 deletions
diff --git a/wine.eselect b/wine.eselect
index 73300b7..68fa105 100644
--- a/wine.eselect
+++ b/wine.eselect
@@ -1,896 +1,375 @@
# -*-eselect-*- vim: ft=eselect
-# Copyright 2005-2017 Gentoo Foundation
+# Copyright 2022 Gentoo Authors
# Distributed under the terms of the GNU GPL version 2 or later
-inherit config multilib tests
-
-DESCRIPTION="Manage active wine version"
+DESCRIPTION="Manage active Wine slots and variants"
MAINTAINER="wine@gentoo.org"
VERSION="1.2.3"
-CONFIG_DIR="/etc/eselect/wine"
-
-VARIANTS=(
- vanilla
- staging
- proton
-)
-
-################################################################################
-# Eselect Wine #
-################################################################################
-
-# Verify that files exist for specified target
-# Input: ${P}
-is_valid_target(){
- if [[ $# -ne 1 ]]; then
- die "Invalid number of parameters"
- fi
-
- local tgt="$1"
-
- set_dir_env
-
- if [[ ! -d "${wine_bin}" ]] || \
- [[ ! "$(ls -A ${wine_bin})" ]] || \
- [[ ! -e "${wine_bin}/wine" ]]; then
- return 1
- elif [[ ! -e "${EPREFIX}/usr/bin/${tgt}" ]]; then
- return 1
- else
- return 0
- fi
-
- unset_dir_env
-}
-
-# Verify that symlinks are valid
-are_symlinks_valid() {
- if [[ $# -gt 1 ]]; then
- die "Invalid number of parameters"
- fi
-
- local v="wine"
-
- while [[ $# -gt 0 ]]; do
- if [[ $1 == --* ]]; then
- local flag="${1#--}"
- if has "${flag}" ${VARIANTS[@]}; then
- v=${flag}
- else
- die "Invalid variant"
- fi
- else
- die "Invalid parameter"
+# Setup env and run $@ in ${EROOT}${WINEETC} to simplify path
+# handling (all other wine-* functions must be ran from this).
+# Passing '-r' skips the write sanity check.
+wine-run() {
+ local WINEETC=/etc/eselect/wine
+ local WINEREL=../../..
+
+ [[ -d ${EROOT}${WINEETC} ]] || mkdir -p -- "${EROOT}${WINEETC}"
+ pushd -- "${EROOT}${WINEETC}" >/dev/null ||
+ die -q "could not change directory to '${EROOT}${WINEETC}'"
+ [[ ${1} == -r ]] && shift || [[ -w . ]] ||
+ die -q "No write access to '${PWD}'"
+
+ local shopt_reset
+ shopt_reset=$(shopt -p nullglob)
+ shopt -s nullglob
+
+ local -A WINEMAP
+ wine-winemap
+
+ "${@}"
+
+ # hack wrt update given PATH is not updated in pkg_postinst (noisy)
+ [[ ${PATH} == @(|*:)"${EPREFIX}${WINEETC}/bin"*(/)@(|:*) || \
+ ${1} == wine-update ]] ||
+ write_warning_msg "'${EPREFIX}${WINEETC}/bin' missing from PATH, may need to run '. ${EROOT}/etc/profile'"
+
+ ${shopt_reset}
+ popd >/dev/null || die
+}
+
+# Run $@ for each valid wine slot, and set:
+# dir_bin,inc,shr,win: relative path to bin, include, share and wine lib dir,
+# dir_wrp: relative path to wine wrappers location (/usr/bin)
+# slot: wine-<variant>-<version>
+# suffix: <variant>-<version>
+# variant: <variant>
+# is_last: true if last slot, false otherwise
+# is_last_variant: true if last of a variant, false otherwise
+# Returns 1 if no valid slots were found.
+wine-foreach_slot() {
+ # try non-POSIX -V to roughly sort by version, keep glob order if can't
+ local fe_sorted fe_dirs=("${WINEREL}"/usr/lib/wine-*-[0-9]*)
+ mapfile -t fe_sorted < <(printf "%s\n" "${fe_dirs[@]}" | sort -V 2>/dev/null)
+ (( ${#fe_sorted[@]} == ${#fe_dirs[@]} )) || fe_sorted=("${fe_dirs[@]}")
+
+ local slot variant dir_bin dir_inc dir_shr dir_win
+ local is_last=false is_last_variant=false fe_run=false fe_valid=false
+ local fe_dir fe_newslot fe_newvariant fe_newsuffix
+ for fe_dir in "${fe_sorted[@]}"; do
+ [[ ${fe_dir} =~ /(wine-(([^-]+)-[0-9][^/]*))$ ]] || continue
+ fe_newslot=${BASH_REMATCH[1]}
+ fe_newsuffix=${BASH_REMATCH[2]}
+ fe_newvariant=${BASH_REMATCH[3]}
+ if ${fe_run}; then
+ fe_run=false
+ [[ ${fe_newvariant} != "${variant}" ]] && is_last_variant=true
+ "${@}"
+ is_last_variant=false
fi
- shift
- done
- local v_arg
- if [[ ${v} != "wine" ]]; then
- v_arg="--${v}"
- fi
-
- local active=$(get_active ${v_arg})
- local tgt="${active}"
- if [[ "${active}" == "(unset)" ]]; then
- write_error_msg "Invalid active config"
- return 1
- fi
-
- set_dir_env
-
- local possible_vars=( bin man include )
- local symlink_vars=$(load_config "${CONFIG_DIR}/links/${v}" symlink_dirs)
- if [[ -z "${symlink_vars}" ]]; then
- write_error_msg "Missing any configured symlink_dirs"
- return 1
- fi
- local var
-
- for var in ${possible_vars[@]}; do
- if has ${var} ${symlink_vars[@]}; then
- symlink_vars=$(list_rm_item "${var}" "${symlink_vars}")
- else
- write_warning_msg "Missing '${var}' in ${v} config"
- write_warning_msg "Might want to re-run set or update"
- fi
+ slot=${fe_newslot}
+ suffix=${fe_newsuffix}
+ variant=${fe_newvariant}
+ dir_bin=${fe_dir}/bin
+ dir_inc=${WINEREL}/usr/include/${slot}
+ dir_shr=${WINEREL}/usr/share/${slot}
+ dir_win=${fe_dir}/wine
+ dir_wrp=${WINEREL}/usr/bin
+ [[ -e ${dir_bin}/wine && -d ${dir_inc} && -d ${dir_shr} && \
+ -d ${dir_win} && -d ${dir_wrp} ]] || continue
+
+ wine-legacy_checks || continue
+
+ fe_run=true
+ fe_valid=true
done
- if [[ ! -z ${symlink_vars} ]]; then
- write_error_msg "Config contains unknown symlink_dirs ${symlink_vars}"
- return 1
- fi
-
- symlink_vars=$(load_config "${CONFIG_DIR}/links/${v}" symlink_dirs)
- for var in ${symlink_vars[@]}; do
- local symlinks=$(load_config "${CONFIG_DIR}/links/${v}" ${var})
- local symlink
-
- if [[ -z "${symlinks}" ]]; then
- die -q "Missing listing of ${var} symlinks"
+ is_last=true
+ is_last_variant=true
+ ${fe_run} && "${@}"
+
+ ${fe_valid}
+}
+
+# Remove all known files we can create
+wine-reset() {
+ local p rm=() rmdir=()
+ for p in bin/* bin include share wine wine.conf; do
+ # only wildcard delete links + empty dirs
+ if [[ -L ${p} || ( ${p} == @(bin/wine|wine.conf) && -e ${p} ) ]]; then
+ rm+=("${p}")
+ elif [[ -d ${p} ]]; then
+ rmdir+=("${p}")
fi
- for symlink in ${symlinks[@]}; do
- if [[ ! -L ${symlink} ]]; then
- write_error_msg "${symlink} is not a symlink"
- return 1
- else
- local file=$(canonicalise ${symlink})
- if [[ ! -e "${file}" ]]; then
- write_error_msg "${symlink} points to nonexistant ${file}"
- return 1
- # Handle bin separately because symlinks don't go to wine_${var}
- elif [[ "${var}" == "bin" ]]; then
- local path="${symlink%${v_arg#-}}${tgt#wine}"
- if [[ "${file}" != "${path}" ]]; then
- write_error_msg "${symlink} points to ${file}"
- write_error_msg "which doesn't appear to be the proper link"
- return 1
- fi
- else
- local path=wine_${var}
- path=${!path}
- path=$(canonicalise "${path}")
- if ! [[ "${file}" =~ "${path%/}"(/*)? ]]; then
- write_error_msg "${symlink} points to ${file}"
- write_error_msg "which doesn't appear to be part of wine"
- return 1
- fi
- fi
- fi
- done
done
- unset_dir_env
-}
-
-
-# print currently selected wine
-get_active() {
- if [[ $# -gt 1 ]]; then
- die -q "Invalid number of parameters specified"
- fi
-
- local v="wine"
-
- while [[ $# -gt 0 ]]; do
- if [[ $1 == --* ]]; then
- local flag="${1#--}"
- if has "${flag}" ${VARIANTS[@]}; then
- v=${flag}
- else
- die -q "Invalid variant"
+ (( ! ${#rm[@]} )) || rm -- "${rm[@]}" &&
+ (( ! ${#rmdir[@]} )) || rmdir -- "${rmdir[@]}" ||
+ die -q "failed to remove some files from '${PWD}', please cleanup"
+}
+wine-reset-feedback() {
+ wine-reset
+ write_warning_msg "Removed all known files from '${PWD}'"
+}
+
+# Set WINEMAP associative array for current slot selections,
+# with 'main' being what you get if call 'wine' without suffix.
+# e.g. ${WINEMAP[vanilla]} == wine-vanilla-7.0
+wine-winemap() {
+ WINEMAP=()
+ if [[ -f wine.conf ]]; then
+ local wine
+ while read -r wine; do
+ if [[ ${wine} =~ ^wine-([^-]+)-[0-9].* ]]; then
+ WINEMAP[${BASH_REMATCH[1]}]=${wine}
+ [[ -v WINEMAP[main] ]] || WINEMAP[main]=${wine}
fi
- else
- [[ -z $1 ]] || die -q "Invalid parameter"
- fi
- shift
- done
-
- local active=$(load_config "${CONFIG_DIR}/active" ${v})
-
- if [[ -z "${active}" ]]; then
- echo "(unset)"
+ done < wine.conf || die
else
- echo "${active}"
+ wine-legacy_winemap
fi
}
-get_installed(){
- if [[ $# -gt 1 ]]; then
- die -q "Invalid number of parameters specified"
- fi
-
- local v="wine"
-
- while [[ $# -gt 0 ]]; do
- if [[ $1 == --* ]]; then
- local flag="${1#--}"
- if has "${flag}" ${VARIANTS[@]}; then
- v=${flag}
- else
- die -q "Invalid variant"
- fi
- else
- die -q "Invalid parameter"
- fi
- shift
- done
-
- local installed=$(load_config "${CONFIG_DIR}/installed" ${v})
-
- echo $(sort_list ${installed[@]})
-}
-
-### Registration action ##
-describe_register(){
- echo "Register a new package with the eselect module (Internal use only)"
-}
-
-describe_register_parameters() {
- echo "<target>"
-}
-
-describe_register_options() {
- for v in ${VARIANTS[@]}; do
- echo "--${v} : Register a new package with ${v}"
- done
- echo "target : A fully qualified variant e.g."
- echo " : wine-1.9.23, wine-vanilla-2.0, or wine-staging-2.1.1"
-}
-
-do_register(){
- if [[ $# -lt 1 ]] || [[ $# -gt 3 ]]; then
- die -q "Invalid number of parameters specified"
- fi
-
- local v="wine"
-
- while [[ $# -gt 0 ]]; do
- if [[ $1 == --* ]]; then
- local flag="${1#--}"
- if has "${flag}" ${VARIANTS[@]}; then
- v=${flag}
- else
- die -q "Invalid flag or variant"
- fi
- else
- local tgt="$1"
- fi
+# Store WINEMAP to wine.conf
+wine-winemap_save() {
+ (
+ echo "# auto-generated by eselect-wine-${VERSION}, do not edit"
+ [[ -v WINEMAP[main] ]] && echo "${WINEMAP[main]}"
+ unset 'WINEMAP[main]'
+ (( ${#WINEMAP[@]} )) && printf '%s\n' "${WINEMAP[@]}"
+ :
+ ) > wine.conf || die
+}
+
+### eselect commands
+
+describe_list() { echo "List available Wine slots and variants"; }
+describe_list_parameters() { echo "[variant]"; }
+describe_list_options() { echo "variant: Variant to list (all if ommitted)"; }
+do_list() { wine-run -r wine-list "${@}"; }
+wine-list() {
+ (( ${#} < 2 )) || die -q "Too many arguments"
+
+ local target
+ local -i count=0
+ write_list_start "Available Wine slots${1:+ for ${1}}:"
+ wine-list_foreach() {
+ count+=1
+ [[ ${1} == all || ${1} == "${variant}" ]] || return 0
+ target=${slot}
+ [[ -v 'WINEMAP[${variant}]' && ${WINEMAP[${variant}]} == "${slot}" ]] &&
+ target=$(highlight_marker "${target}")
+ [[ -v WINEMAP[main] && ${WINEMAP[main]} == "${slot}" ]] &&
+ ! is_output_mode brief && target+=" ($(highlight main))"
+ write_numbered_list_entry ${count} "${target}"
+ ${is_last_variant} && ! ${is_last} && [[ ${1} == all ]] &&
+ ! is_output_mode brief && echo
+ }
+ wine-foreach_slot wine-list_foreach "${1:-all}"
+ [[ -v target ]] || write_numbered_list -m "(none found)"
+}
+
+describe_update() { echo "Auto-select highest slot for each Wine variants"; }
+describe_update_parameters() { echo "[--if-unset] [variant]"; }
+describe_update_options() {
+ echo "--if-unset: Only update if selected slots are invalid"
+ echo "variant: Only update the given variant, unless invalid"
+}
+do_update() { wine-run wine-update "${@}"; }
+wine-update() {
+ local ifunset variant_only
+ while (( ${#} )); do
+ case ${1} in
+ --if-unset) ifunset=1;;
+ --reset) wine-reset-feedback; return;; # private option
+ --all|--any|--d3d9|--proton|--staging|--vanilla);; # legacy
+ --*) die -q "Unrecognized option '${1}'";;
+ *)
+ [[ ! -v variant_only ]] || die -q "Too many arguments"
+ if [[ ${1} != all ]]; then
+ ifunset=1
+ variant_only=${1}
+ fi
+ ;;
+ esac
shift
done
- if [[ -z "${tgt}" ]]; then
- die -q "Target not specified"
- fi
-
- local v_arg
- if [[ ${v} != "wine" ]]; then
- v_arg="--${v}"
- fi
-
- if is_number "${tgt}"; then
- local tgts=($(get_installed ${v_arg}))
- tgt=${tgts[${tgt}-1]}
- fi
-
- if ! is_valid_target "${tgt}"; then
- die -q "Target does not exist"
- fi
-
- local list=$(get_installed ${v_arg})
-
- if ! has ${tgt} ${list}; then
- list=($(sort_list "${list} ${tgt}"))
- store_config "${CONFIG_DIR}/installed" ${v} "${list[@]}"
- fi
-}
-
-describe_deregister(){
- echo "Deregister a package with the eselect module (Internal use only)"
-}
-
-describe_deregister_parameters() {
- echo "<target>"
-}
-
-describe_deregister_options() {
- for v in ${VARIANTS[@]}; do
- echo "--${v} : Deregister a package with ${v}"
- done
- echo "--force : Forcibly remove a package"
- echo "target : A fully qualified variant e.g."
- echo " : wine-1.9.23, wine-vanilla-2.0, or wine-staging-2.1.1"
-}
-
-do_deregister(){
- if [[ $# -lt 1 ]] || [[ $# -gt 3 ]]; then
- die -q "Invalid number of parameters specified"
- fi
-
- local v="wine"
- local force=false
-
- while [[ $# -gt 0 ]]; do
- if [[ $1 == --* ]]; then
- local flag="${1#--}"
- if has "${flag}" ${VARIANTS[@]}; then
- v=${flag}
- elif [[ "${flag}" == "force" ]]; then
- force=true
- else
- die -q "Invalid variant"
+ wine-reset
+
+ local bin display wrap
+ local -A is_done=()
+ wine-update_foreach() {
+ if ${is_last_variant} ||
+ [[ -v ifunset && ${variant_only} != "${variant}" && \
+ ${WINEMAP[${variant}]} == "${slot}" ]] &&
+ [[ ! -v 'is_done[${variant}]' ]]
+ then
+ [[ -d bin ]] || mkdir bin || die
+
+ # wine does not react well to renames, so use variant wrappers
+ for bin in "${dir_bin}"/*; do
+ wrap=${dir_wrp}/${bin##*/}-${suffix}
+ [[ ! -e ${wrap} ]] ||
+ ln -s -- "../${wrap}" "bin/${bin##*/}-${variant}" || die
+ done
+
+ display=
+ [[ ${WINEMAP[${variant}]} != "${slot}" ]] &&
+ display="${slot} is set as ${variant} provider (auto)"
+
+ if ${is_last} ||
+ { ${is_last_variant} &&
+ [[ ${WINEMAP[main]} == "${WINEMAP[${variant}]}" ]]; } ||
+ [[ -v ifunset && ${variant_only} != "${variant}" && \
+ ${WINEMAP[main]} == "${slot}" ]] &&
+ [[ ! -v is_done[main] ]]
+ then
+ # could skip wrappers here, but use for consistency
+ for bin in "${dir_bin}"/*; do
+ wrap=${dir_wrp}/${bin##*/}-${suffix}
+ [[ ! -e ${wrap} ]] ||
+ ln -s -- "../${wrap}" "bin/${bin##*/}" || die
+ done
+ ln -s -- "${dir_inc}" include || die
+ ln -s -- "${dir_shr}" share || die
+ ln -s -- "${dir_win}" wine || die
+ [[ ${WINEMAP[main]} != "${slot}" ]] &&
+ display="${slot} is set as the main provider (auto)"
+ is_done[main]=1
+ WINEMAP[main]=${slot}
fi
- else
- local tgt="$1"
- fi
- shift
- done
-
- if [[ -z "${tgt}" ]]; then
- die -q "Target not specified"
- fi
-
- local v_arg
- if [[ ${v} != "wine" ]]; then
- v_arg="--${v}"
- fi
-
- if is_number "${tgt}"; then
- local tgts=($(get_installed ${v_arg}))
- tgt=${tgts[${tgt}-1]}
- fi
- if ! is_valid_target "${tgt}" && [[ ${force} == "false" ]]; then
- die -q "Target does not exist"
- fi
-
- local list=$(get_installed ${v_arg})
-
- if ! has ${tgt} ${list}; then
- die -q "${tgt} is not registered for ${v}"
- fi
+ [[ ${display} ]] && echo "${display}"
- if [[ "${tgt}" == "$(get_active ${v_arg})" ]]; then
- do_unset ${v_arg}
- fi
-
- list=$(list_rm_item ${tgt} "${list}")
- store_config "${CONFIG_DIR}/installed" ${v} "${list}"
-}
-
-### list action ###
-
-describe_list() {
- echo "List available wine versions"
-}
-
-describe_list_options() {
- for v in ${VARIANTS[@]}; do
- echo "--${v} : List the available 'wine-${v}'"
- done
-}
-
-do_list() {
- if [[ $# -gt 1 ]]; then
- die -q "Invalid number of parameters specified"
- fi
-
- local v="wine"
-
- while [[ $# -gt 0 ]]; do
- if [[ $1 == --* ]]; then
- local flag="${1#--}"
- if has "${flag}" ${VARIANTS[@]}; then
- v=${flag}
- else
- die -q "Invalid variant"
- fi
- else
- die -q "Invalid parameter"
+ is_done[${variant}]=1
+ WINEMAP[${variant}]=${slot}
fi
- shift
- done
-
- local v_arg
- if [[ ${v} != "wine" ]]; then
- v_arg="--${v}"
- fi
-
- write_list_start "Available wine${v_arg#-} versions:"
- local installed=($(get_installed ${v_arg}))
- local active=$(get_active ${v_arg})
-
- if [[ ${#installed} -eq 0 ]]; then
- unset installed
- else
- for (( i = 0; i < ${#installed[@]}; i++ )); do
- if [[ ${installed[i]} = ${active} ]]; then
- installed[i]=$(highlight_marker "${installed[i]}")
- fi
+ }
+ if wine-foreach_slot wine-update_foreach; then
+ # cleanup unused before saving
+ local variant
+ for variant in "${!WINEMAP[@]}"; do
+ [[ -v 'is_done[${variant}]' ]] || unset "WINEMAP[${variant}]"
done
- fi
-
- write_numbered_list -m "(none found)" "${installed[@]}"
-}
-
-### show action ###
-
-describe_show() {
- echo "Show the active wine version"
-}
-
-describe_show_options() {
- for v in ${VARIANTS[@]}; do
- echo "--$v : Show the active 'wine-$v'"
- done
-}
-
-do_show() {
- if [[ $# -gt 1 ]]; then
- die -q "Invalid number of parameters specified"
- fi
-
- local v="wine"
-
- while [[ $# -gt 0 ]]; do
- if [[ $1 == --* ]]; then
- local flag="${1#--}"
- if has "${flag}" ${VARIANTS[@]}; then
- v=${flag}
- else
- die -q "Invalid variant"
- fi
- else
- die -q "Invalid parameter"
- fi
- shift
- done
-
- local v_arg
- if [[ ${v} != "wine" ]]; then
- v_arg="--${v}"
- fi
-
- write_list_start "Active wine${v_arg#-} version:"
- local active=$(get_active ${v_arg})
-
- write_kv_list_entry "${active}" ""
- if [[ "${active}" != "(unset)" ]]; then
- are_symlinks_valid ${v_arg}
+ wine-winemap_save
+ else
+ # no wine slots, keep placeholders to avoid broken references
+ mkdir -p bin include share wine
+ printf "#!/usr/bin/env sh\necho 'Error: Wine is not setup (eselect-wine)' >&2\nexit 1\n" \
+ > bin/wine
+ chmod +x bin/wine
fi
}
-### unset action ###
-
-describe_unset() {
- echo "Remove wine symlinks"
-}
-
-describe_unset_options() {
- for v in ${VARIANTS[@]}; do
- echo "--$v : Remove the 'wine-$v' symlinks"
- done
- echo "--all : Unset active wine and all variants"
-}
-
-do_unset() {
- if [[ $# -gt 1 ]]; then
- die -q "Invalid number of parameters specified"
- fi
-
- local v="wine"
- local all=false
-
- while [[ $# -gt 0 ]]; do
- if [[ $1 == --* ]]; then
- local flag="${1#--}"
- if has "${flag}" ${VARIANTS[@]}; then
- v=${flag}
- elif [[ "${flag}" == "all" ]]; then
- all=true
- else
- die -q "Invalid variant"
- fi
- else
- die -q "Invalid parameter"
- fi
- shift
- done
-
- # Run do_unset for all variants
- if ${all}; then
- do_unset
- for v in ${VARIANTS[@]}; do
- do_unset "--${v}"
- done
+describe_show() { echo "Show the active Wine slot"; }
+describe_show_parameters() { echo "[variant]"; }
+describe_show_options() { echo "variant: Variant to show, e.g. vanilla (main if ommitted)"; }
+do_show() { wine-run -r wine-show "${@}"; }
+wine-show() {
+ (( ${#} < 2 )) || die -q "Too many arguments"
- return 0
- fi
-
- local v_arg
- if [[ ${v} != "wine" ]]; then
- v_arg="--${v}"
+ if [[ -v 'WINEMAP[${1:-main}]' ]]; then
+ echo "${WINEMAP[${1:-main}]}"
+ else
+ write_warning_msg "no slot is selected${1:+ for ${1}}"
fi
-
- remove_symlinks ${v_arg} || die -q "Couldn't remove wine${v_arg#-} symlinks"
-
- store_config "${CONFIG_DIR}/active" "${v}" ""
-}
-
-### set action ###
-
-describe_set() {
- echo "Set a new wine version"
-}
-
-describe_set_parameters() {
- echo "<target>"
}
+describe_set() { echo "Set active Wine slots and variants"; }
+describe_set_parameters() { echo "[--only] <target>"; }
describe_set_options() {
- for v in ${VARIANTS[@]}; do
- echo "--$v : Set only the 'wine-$v' symlinks"
- done
- echo "target : Target name or number (from 'list' action)"
-}
-
-do_set() {
- if [[ $# -lt 1 ]] || [[ $# -gt 2 ]]; then
- die -q "Invalid number of parameters specified"
- fi
-
- local v="wine"
-
- while [[ $# -gt 0 ]]; do
- if [[ $1 == --* ]]; then
- local flag="${1#--}"
- if has "${flag}" ${VARIANTS[@]}; then
- v=${flag}
- else
- die -q "Invalid flag or variant"
- fi
- else
- local tgt="$1"
- fi
+ echo "--only: Only set the variant's slot"
+ echo "target: Target name or number (from 'list' action)"
+}
+do_set() { wine-run wine-set "${@}"; }
+wine-set() {
+ local chosen_slot only
+ while (( ${#} )); do
+ case ${1} in
+ --only) only=1;;
+ --*) die -q "Unrecognized option '${1}'";;
+ *)
+ [[ ! -v chosen_slot ]] || die -q "Too many arguments"
+ chosen_slot=${1}
+ ;;
+ esac
shift
done
-
- if [[ -z "${tgt}" ]]; then
- die -q "Target not specified"
- fi
-
- local v_arg
- if [[ ${v} != "wine" ]]; then
- v_arg="--${v}"
- fi
-
- if is_number "${tgt}"; then
- local tgts=($(get_installed ${v_arg}))
- tgt=${tgts[${tgt}-1]}
- fi
-
- if ! is_valid_target "${tgt}"; then
- die -q "Target does not exist"
- fi
-
- do_unset ${v_arg} || die -q "Failed to unset active target"
- set_symlinks ${v_arg} "${tgt}" || die -q "Couldn't set wine-${v_arg#-} symlinks"
-
- store_config "${CONFIG_DIR}/active" "${v}" "${tgt}"
-}
-
-### update action ###
-
-describe_update() {
- echo "Set highest version installed active"
-}
-
-describe_update_options() {
- for v in ${VARIANTS[@]}; do
- echo "--$v : Update the 'wine-$v' symlinks"
- done
- echo "--all : Update main active wine and all variants"
- echo "--if-unset : Reuse currently selected version if it appears valid"
-}
-
-do_update() {
- if [[ $# -gt 3 ]]; then
- die -q "Invalid number of parameters specified"
- fi
-
- local v="wine"
- local if_unset=false
- local all=false
-
- while [[ $# -gt 0 ]]; do
- if [[ $1 == --* ]]; then
- local flag="${1#--}"
- if has "${flag}" ${VARIANTS[@]}; then
- v=${flag}
- elif [[ "${flag}" == "if-unset" ]]; then
- if_unset=true
- elif [[ "${flag}" == "all" ]]; then
- all=true
- else
- die -q "Invalid flag or variant"
+ [[ -v chosen_slot ]] || die -q "Please specify a target to activate"
+
+ local -i chosen_num count=1
+ printf -v chosen_num %u "${chosen_slot}" 2>/dev/null &&
+ unset chosen_slot
+
+ local display
+ wine-set_foreach() {
+ if (( chosen_num == count++ )) || [[ ${chosen_slot} == "${slot}" ]]; then
+ display="${slot} is set the ${variant} provider"
+ [[ ${WINEMAP[${variant}]} == "${slot}" ]] &&
+ display="${slot} is already set as the ${variant} provider"
+ WINEMAP[${variant}]=${slot}
+ if [[ ! -v only ]]; then
+ display="${slot} is set as the main provider"
+ [[ ${WINEMAP[main]} == "${slot}" ]] &&
+ display="${slot} is already set as the main provider"
+ WINEMAP[main]=${slot}
fi
- else
- die -q "Invalid parameter"
- fi
- shift
- done
-
- if [[ "${v}" != "wine" ]] && ${all}; then
- die -q "Either specify a specific variant, or all, but not both"
- fi
-
- # Run do_update for all variants
- if ${all}; then
- local unset_arg
- if ${if_unset}; then
- unset_arg="--if-unset"
- fi
-
- do_update ${unset_arg}
- for v in ${VARIANTS[@]}; do
- do_update "--${v}" ${unset_arg}
- done
-
- return 0
- fi
-
- local v_arg
- if [[ ${v} != "wine" ]]; then
- v_arg="--${v}"
- fi
-
- # Determine if set and valid
- # If so, return
- if ${if_unset}; then
- local active=$(get_active ${v_arg})
- if is_valid_target "${active}" && are_symlinks_valid ${v_arg}; then
- return 0
fi
- fi
-
- local installed=($(get_installed ${v_arg}))
- if [[ ${#installed[@]} -eq 0 ]]; then
- write_warning_msg "Skipping wine${v_arg#-}. No registered targets found."
- return 0
- fi
- local tgt=${installed[-1]}
-
- do_set ${v_arg} "${tgt}" || die -q "Couldn't set new wine${v_arg#-} symlinks"
-}
+ }
+ wine-foreach_slot wine-set_foreach
+ [[ -v display ]] ||
+ die -q "Target '${chosen_slot:-${chosen_num}}' was not found (select from 'list' action)"
+ wine-update --if-unset
-# lifted from fdo-mime.eclass
-desktop_database_update() {
- if [[ -x "${EPREFIX}/usr/bin/update-desktop-database" ]]; then
-# echo "Updating desktop mime database ..."
- "${EPREFIX}/usr/bin/update-desktop-database" -q "${EPREFIX}/usr/share/applications" || die
- fi
+ echo "${display}"
}
-# sort function for versions, to be used in a pipe
-sort_versions() {
- local vsort="sort --version-sort"
- # Test if our sort supports the --version-sort option (posix does)
- ${vsort} </dev/null &>/dev/null || vsort=sort
-
- # We sort versions as follows:
- # 1. Run sed to prepend the version string by the numeric version
- # 1.7.21 wine-1.7.21
- # 1.7.14 wine-compholio-1.7.14
- # 2. sort --version-sort
- # 3. Run sed again to remove the prepended keys from step 1.
- sed -e 's/^\(.\+-\)\([[:digit:].]*\)$/\2 &/' \
- | LC_ALL=C ${vsort} | sed 's/.* //'
-}
+### legacy junk beyond here waiting for cleanup (~2025?)
-# Takes a list of items and returns a sorted version
-sort_list() {
- list=($@)
- if [[ ! -z "${list}" ]]; then
- for i in ${list[@]}; do
- echo "${i}"
- done | sort_versions
+wine-legacy_checks() {
+ # need to be ran in postrm, not pre.. so we need a way to know we
+ # should ignore the slot that's about to be removed (not the end
+ # of the world if this fails so rely on dodgy methods, dead links
+ # will be fixed on the next `eselect wine update`)
+ if [[ ${EBUILD_PHASE_FUNC} == pkg_prerm && ${P} == "${slot}" ]]; then
+ return 1
fi
-}
-# Returns a list excluding the specified item
-# list_rm_item [rm_this] [list]
-list_rm_item() {
- if [[ $# -lt 2 ]]; then
- die "Not enough arguments"
+ if [[ -d ${WINEREL}/usr/lib64/${slot} ]]; then
+ write_warning_msg "ignored legacy installation at ${EROOT}/usr/lib64/${slot}"
+ [[ -e ${WINEREL}/usr/bin/${slot} ]] &&
+ write_warning_msg "should still be usable by calling versioned ${EROOT}/usr/bin/${slot}"
+ return 1
fi
-
- rm_this=$1
- shift
- list=($@)
-
- local i
- for i in ${!list[@]};do
- if [ "${list[$i]}" == "${rm_this}" ]; then
- unset list[$i]
- fi
- done
-
- echo ${list[@]}
}
-remove_symlinks() {
- if [[ $# -gt 1 ]]; then
- die -q "Invalid number of parameters specified"
- fi
-
- local v="wine"
-
- while [[ $# -gt 0 ]]; do
- if [[ $1 == --* ]]; then
- local flag="${1#--}"
- if has "${flag}" ${VARIANTS[@]}; then
- v=${flag}
- else
- die -q "Invalid flag or variant"
- fi
- else
- die -q "Invalid parameter"
- fi
- shift
- done
-
- local v_arg
- if [[ ${v} != "wine" ]]; then
- v_arg="--${v}"
- fi
-
- local symlink_vars=$(load_config "${CONFIG_DIR}/links/${v}" symlink_dirs)
- if [[ -z "${symlink_vars}" ]]; then
- return 0
- fi
- local var
- for var in ${symlink_vars[@]}; do
- local symlinks=$(load_config "${CONFIG_DIR}/links/${v}" ${var})
- local symlink
- if [[ -z "${symlinks}" ]]; then
- die -q "Missing listing of ${var} symlinks"
- fi
- for symlink in ${symlinks[@]}; do
- if [[ -e "${symlink}" ]]; then
- if [[ ! -L "${symlink}" ]]; then
- die -q "${symlink} is not a symlink."
- fi
- rm "${symlink}" || die "Failed to rm ${symlink}"
- else
- write_warning_msg "${symlink} symlink was missing."
- fi
-
- # remove entry from config file
- symlinks=$(list_rm_item "${symlink}" "${symlinks}")
+inherit config
+wine-legacy_winemap() {
+ # this is created by the eselect-wine ebuild to keep same slots
+ if [[ -f eselect-wine-migration ]]; then
+ local active variant
+ for variant in proton staging vanilla wine; do
+ active=$(load_config eselect-wine-migration ${variant})
+ [[ ${variant} == wine ]] && variant=main
+ [[ ${active} ]] && WINEMAP[${variant}]=${active}
done
- store_config "${CONFIG_DIR}/links/${v}" ${var} "${symlinks}"
-
- # remove set from config file
- symlink_vars=$(list_rm_item "${var}" "${symlink_vars}")
-
- store_config "${CONFIG_DIR}/links/${v}" symlink_dirs "${symlink_vars}"
- done
-
- # Remove active if it exists
- store_config "${CONFIG_DIR}/active" "${v}" ""
-
- local desktop="${EPREFIX}/usr/share/applications/wine${v_arg#-}.desktop"
- if [[ -e "${desktop}" ]]; then
- rm "${desktop}" || die "Failed ro remove desktop file"
- fi
- desktop_database_update || die "Failed to update xorg desktop database"
-}
-
-set_symlinks() {
- if [[ $# -lt 1 ]] || [[ $# -gt 2 ]]; then
- die -q "Invalid number of parameters specified"
- fi
-
- local v="wine"
-
- while [[ $# -gt 0 ]]; do
- if [[ $1 == --* ]]; then
- local flag="${1#--}"
- if has "${flag}" ${VARIANTS[@]}; then
- v=${flag}
- else
- die -q "Invalid flag or variant"
- fi
- else
- local tgt="$1"
- fi
- shift
- done
-
- if [[ -z "${tgt}" ]]; then
- die -q "Target not specified"
fi
-
- local v_arg
- if [[ ${v} != "wine" ]]; then
- v_arg="--${v}"
- fi
-
- if is_number "${tgt}"; then
- local tgts=($(get_installed ${v_arg}))
- tgt=${tgts[${tgt}-1]}
- fi
-
- if ! is_valid_target "${tgt}"; then
- die -q "Target does not exist"
- fi
-
- set_dir_env
-
- local link
- local links
- (
- shopt -s failglob
-
- store_config "${CONFIG_DIR}/links/${v}" symlink_dirs "bin"
- store_config "${CONFIG_DIR}/links/${v}" "bin" ""
- for b in "${wine_bin}"/*; do
- link="${EPREFIX}/usr/bin/${b##*/}${v_arg#-}"
- local linktgt="${EPREFIX}/usr/bin/${b##*/}${tgt##wine}"
- if [[ -L "${link}" ]]; then
- write_warning_msg "${link} already exists, overwriting"
- rm "${link}" || die -q "Failed to rm old link: ${link}"
- fi
- ln -s "${linktgt}" "${link}"
- if [[ $? -ne 0 ]]; then
- write_warning_msg "Failed to set symlink from ${linktgt} to ${link}"
- write_warning_msg "Cleaning up"
- remove_symlinks ${v_arg}
- fi
- links="${links} ${link}"
- done
- store_config "${CONFIG_DIR}/links/${v}" "bin" "${links}"
-
- shopt -s globstar
- links=""
- append_config "${CONFIG_DIR}/links/${v}" symlink_dirs "man"
- store_config "${CONFIG_DIR}/links/${v}" "man" ""
- pushd "${wine_man}" > /dev/null
- for m in **/*.1; do
- link="${EPREFIX}/usr/share/man/${m}${v_arg#-}"
- if [[ -L "${link}" ]]; then
- write_warning_msg "${link} already exists, overwriting"
- rm "${link}" || die -q "Failed to rm old link: ${link}"
- fi
- mkdir -p "${link%/*}" || die -q "Failed to mkdir: ${link%/*}"
- ln -s "${wine_man}/${m}" "${link}"
- if [[ $? -ne 0 ]]; then
- write_warning_msg "Failed to set symlink from ${wine_man}/${m} to ${link}"
- write_warning_msg "Cleaning up"
- remove_symlinks ${v_arg}
- fi
- links="${links} ${link}"
- done
- append_config "${CONFIG_DIR}/links/${v}" "man" "${links}"
- popd > /dev/null
-
- append_config "${CONFIG_DIR}/links/${v}" symlink_dirs "include"
- store_config "${CONFIG_DIR}/links/${v}" "include" ""
- link="${EPREFIX}/usr/include/wine${v_arg#-}"
- local linktgt="${wine_include}"
- if [[ -L "${link}" ]]; then
- write_warning_msg "${link} already exists, overwriting"
- rm "${link}" || die -q "Failed to rm old link: ${link}"
- fi
- ln -s "${linktgt}" "${link}"
- if [[ $? -ne 0 ]]; then
- write_warning_msg "Failed to set symlink from ${linktgt} to ${link}"
- write_warning_msg "Cleaning up"
- remove_symlinks ${v_arg}
- fi
- store_config "${CONFIG_DIR}/links/${v}" "include" "${link}"
-
-
- local desktop="${EPREFIX}/usr/share/applications/wine${v_arg#-}.desktop"
- cp "${wine_app}/wine.desktop" "${desktop}" || die "Failed to copy desktop file"
- sed -i "s:Exec=.*:Exec=wine${v_arg#-} start /unix %f:" ${desktop} || die "Failed to edit desktop file"
- desktop_database_update || die "Failed to update xorg desktop database"
-
- )
- unset_dir_env
-}
-
-# set env vars for us to work with
-set_dir_env() {
- wine_bin="${EPREFIX}/usr/lib/${tgt}/bin"
- wine_include="${EPREFIX}/usr/include/${tgt}/wine"
- wine_share="${EPREFIX}/usr/share/${tgt}"
- wine_app="${wine_share}/applications"
- wine_man="${wine_share}/man"
}
-# unset our env vars
-unset_dir_env() {
- unset wine_{bin,include,share,app,man}
+# no eselect method to hide options, so describe as deprecated
+describe_deregister() { echo "(deprecated)"; }
+do_deregister() { :; }
+describe_register() { echo "(deprecated)"; }
+do_register() {
+ write_warning_msg "'eselect wine register' is deprecated, please migrate to:"
+ echo '
+ IDEPEND=">=app-eselect/eselect-wine-2"
+ pkg_postinst() {
+ eselect wine update --if-unset || die
+ }
+ pkg_postrm() { # /not/ prerm
+ eselect wine update --if-unset || die
+ }
+' >&2
}