config / .fgfs / fgfs_function /
d35f750 4 years ago
1 contributor
263 lines | 12.213kb
#!/bin/zsh

#FGDIR=$HOME/scripts/flightgear
#FGADDON=$HOME/.fgfs/flightgear-fgaddon
function fgfs () {
    local fgfs_source=$FGDIR/source
    local fgfs_build=$FGDIR/build
    local fgfs_install=$FGDIR/install
    function update_fg () {
        case $1 in
            fgaddon)
                DB=$FGADDON/fgaddon.db $HOME/.fgfs/fgaddon
            ;;
            data)
                typeset -A control_system_data=(
                    git pull
                    svn up
                )
                for control_system update_command in ${(kv)control_system_data}; do
                    find $FGADDON \
                        -maxdepth 3 \
                        -mindepth 1 \
                        -type d \
                        -name .${control_system} \
                        -printf "\n[ %h ]\n" \
                        -execdir ${control_system} ${update_command} \;
                done
                unset control_system_data control_system update_command
                ;;
            source)
                typeset -A control_system_data=(
                    git pull
                    svn up
                )
                for control_system update_command in ${(kv)control_system_data}; do
                    find $fgfs_source \
                        -maxdepth 2 \
                        -mindepth 1 \
                        -type d \
                        -name .${control_system} \
                        -printf "\n[ %h ]\n" \
                        -execdir ${control_system} ${update_command} \;
                done
                unset control_system_data control_system update_command
                ;;
            check)
                typeset -A revision builtstatus
                for component in simgear flightgear; do
                    cd $fgfs_source/$component
                    revision[$component]=$(git rev-parse HEAD)
                    cd - > /dev/null 2>&1
                done
                xmlgetnext () {
                   local IFS='>'
                   read -d '<' TAG VALUE
                }
                unset entryid
                wget -qO- http://build.flightgear.org:8080/job/fgfs/rssAll | while xmlgetnext; do
                    case "$TAG" in
                        "entry")
                            let entryid++
                            unset stable jenkins_id updated
                            ;;
                        "title")
                            test -n "$entryid" && stable=$(sed -r 's/^.*\((.+)\)/\1/' <<< "$VALUE")
                            ;;
                        "id")
                            test -n "$entryid" && jenkins_id="${VALUE##*:}"
                            ;;
                        "updated")
                            test -n "$entryid" && updated="$VALUE"
                            ;;
                        "/entry")
                            joburl=http://build.flightgear.org:8080/job/fgfs/$jenkins_id
                            regex='s|^.+<strong>Revision:</strong> (.+)$|\1|p'
                            if test "$(wget -qO- $joburl/git-2/ | sed -rn $regex)" = ${revision[simgear]} -a \
                                    "$(wget -qO- $joburl/git-3/ | sed -rn $regex)" = ${revision[flightgear]}; then
                                echo $(date +"$stable (#$jenkins_id, updated %d %B, %H:%M)" -d "$updated")
                                unset revision builtstatus entryid
                                return 0
                            elif test $entryid -eq 5; then
                                echo $(date +"no build info found (last %d %B, %H:%M)" -d "$updated")
                                unset revision builtstatus entryid
                                return 1
                            fi
                            ;;
                    esac
                done
                ;;
            build)
                local simultaneous=$(nproc)
                local previously_installed=()
                mkdir -p $fgfs_install

                for component in $(<$fgfs_source/ordre); do
# TODO: prendre en compte les cas sans cmake
                    title="*** $component:u ***"
                    printf "\n%s\n%s\n%s\n" "${(l:${#title}::*:)}" "$title" "${(l:${#title}::*:)}"

                    local cmake_options=("-DCMAKE_BUILD_TYPE=Release" "-DCMAKE_INSTALL_PREFIX=$fgfs_install/$component")
                    [[ ${#previously_installed[@]} -gt 0 ]] \
                        && cmake_options+=(${(j. .)${:--DCMAKE_PREFIX_PATH=$fgfs_install/${^previously_installed}}})
                    cmake_options+=("-j$simultaneous")
                    test -e $fgfs_source/${component}.specific && source $fgfs_source/${component}.specific

                    mkdir -p $fgfs_build/$component
                    cd $fgfs_build/$component

                    echo cmake ${cmake_options[@]} $fgfs_source/$component
                    
                    cmake ${cmake_options[@]} $fgfs_source/$component > /dev/null \
                    && make -j$simultaneous > /dev/null \
                    && make install \
                    || {
                        echo "erreur construction $component"
                        return
                    }

                    previously_installed+=($component)
                    cd -
                done
                unset component
                ;;
        esac
    }
    function ld_library_path () {
        IFS_=$IFS
        IFS=$'\n'
        for lib in $(ls -d $FGDIR/install/*/lib); do
            egrep -q "(^|:)$lib(:|$)" <<< "${LD_LIBRARY_PATH}" || LD_LIBRARY_PATH="${lib}${LD_LIBRARY_PATH:+:}${LD_LIBRARY_PATH}"
        done
        IFS=$IFS_
        export LD_LIBRARY_PATH
    }
    local aircrafts="$FGADDON/Aircraft"
    local fgfs_args=("--fg-root=$FGDIR/source/fgdata")
    local aircraft=
    local airport=
    if [[ -o BASH_REMATCH ]]; then
        local bash_rematch_set=1
    fi

    for fgfs_arg in $@; do
        if test ${fgfs_arg#--} = ${fgfs_arg}; then
############ APPAREIL DANS FGADDON ?
            if test -n "$(find $aircrafts -maxdepth 2 -type f -name ${fgfs_arg}-set.xml -print -quit)"; then
                fgfs_args+=("--aircraft=$fgfs_arg")
                fgfs_args+=("--fg-aircraft=$FGADDON/Aircraft")

############ APPAREIL DANS FGDIR/source/fgdata ?
            elif official_aircraft=$(find "$fgfs_source/fgdata/Aircraft" -maxdepth 2 -type f -name ${fgfs_arg}-set.xml -printf "%h" -quit) && test -n "$official_aircraft"; then
                fgfs_args+=("--aircraft=$fgfs_arg")
                fgfs_args+=("--aircraft-dir=$official_aircraft")
                unset official_aircraft

############ APPAREIL DANS FGADDON ?
            elif which sqlite3 > /dev/null 2>&1 \
            && test -r $FGADDON/fgaddon.db \
            && test $(sqlite3 $FGADDON/fgaddon.db <<< "select count(file) from setxml where file is '${fgfs_arg}-set.xml'") -eq 1; then
                model=$(sqlite3 $FGADDON/fgaddon.db <<< "select name from aircrafts inner join setxml on aircrafts.id = setxml.variantof where setxml.file is '${fgfs_arg}-set.xml'")
                read -q "REPLY?download $model ? (y/N) "
                read
                if test -n "$REPLY" && test ${REPLY:l} = "y"; then
                    svn co https://svn.code.sf.net/p/flightgear/fgaddon/trunk/Aircraft/$model $FGADDON/Aircraft/$model
                    fgfs_args+=("--aircraft=$fgfs_arg")
                else
                    echo "aircraft $fgfs_arg isn't installed"
                    return
                fi

############ SERVEUR MULTIPLAY ?
            elif set -o BASH_REMATCH && [[ $fgfs_arg =~ "^mp([0-9]+)$" ]]; then
                fgfs_args+=("--multiplay=out,10,mpserver${BASH_REMATCH[2]}.flightgear.org,5000")
                fgfs_args+=("--callsign=f-zakh")
                test -z "$bash_rematch_set" && set +o BASH_REMATCH

############ DEMANDE DE TRACE DE VOL ?
            elif [[ $fgfs_arg == "log" ]]; then
                # option construite plus tard avec nom de l'appareil
                local log_requested=1

############ AEROPORT ?
            else 
                local candidate_airport=${fgfs_arg%:*}; [[ $candidate_airport == $fgfs_arg ]] && candidate_airport=${fgfs_arg%+*}
                local candidate_parking=${fgfs_arg#*:}; [[ $candidate_parking == $fgfs_arg ]] && unset candidate_parking
                local candidate_runway=${fgfs_arg#*+};  [[ $candidate_runway  == $fgfs_arg ]] && unset candidate_runway
                local terrafs=${candidate_airport#-}

                if [[ $terrafs != $candidate_airport && -x $HOME/.fgfs/terrafs && -d $HOME/.fgfs/terrafs.d ]]; then
                    candidate_airport=$terrafs
                    $HOME/.fgfs/terrafs $HOME/.fgfs/terrafs.d
                    fgfs_args+=(--fg-scenery=$HOME/.fgfs/terrafs.d)
                    fgfs_args+=(--disable-terrasync)
                    local scenes_dir=$HOME/.fgfs/terrafs.d
                else
                    fgfs_args+=(--terrasync-dir=$HOME/.fgfs/TerraSync)
                    fgfs_args+=(--enable-terrasync)
                    local scenes_dir=$HOME/.fgfs/TerraSync
                fi

                local airport_data="$scenes_dir/Airports/$candidate_airport[1]:u/$candidate_airport[2]:u/$candidate_airport[3]:u/${candidate_airport:u}"
                if [[ -a "${airport_data}.threshold.xml" ]]; then
                    fgfs_args+=(--airport=$candidate_airport)
                    if [[ -a "${airport_data}.groundnet.xml" && -n "$candidate_parking" ]]; then
                        if test $candidate_parking = '?'; then
                          echo "Parkings ${candidate_airport:u}:"
                          sed -rn "/<parkingList/,/parkingList>/s/^.* name=\"([^\"]+).*$/\1/p" ${airport_data}.groundnet.xml
                          return
                        elif sed -rn "/<parkingList/,/parkingList>/p" ${airport_data}.groundnet.xml | grep -q "name=\"${candidate_parking}\""; then
                            fgfs_args+=("--parkpos='$candidate_parking'")
                        fi
                    elif test -n "$candidate_runway"; then
                        if test $candidate_runway = '?'; then
                            echo "Runways ${candidate_airport:u}:"
                            sed -rn 's|^.*<rwy>(.+)</rwy>.*$|\1|p' ${airport_data}.threshold.xml
                            return
                        elif grep -q "<rwy>${candidate_runway}</rwy>" ${airport_data}.threshold.xml; then
                            fgfs_args+=("--runway=$candidate_runway")
                        fi
                    fi
                fi
            fi

######## AUTRE OPTION
        else
            case $fgfs_arg in
                --update(-data|-source|-build|-fgaddon|-check|))
                    for up in ${${=${fgfs_arg#--update}:-data source build}#-}; do
                        update_fg $up
                    done
                    unset up
                    return
                    ;;
                --(show-aircraft|help))
                    local -A complement=(
                        --show-aircraft --fg-aircraft=$FGADDON/Aircraft
                        --help          --verbose
                    )
                    ld_library_path
                    $FGDIR/install/flightgear/bin/fgfs $fgfs_arg ${complement[$fgfs_arg]} 2>/dev/null | pager
                    return
                    ;;
                *)
                    fgfs_args+=($fgfs_arg);;
            esac
        fi
    done
    unset fgfs_arg
    if [[ -n "$log_requested" && -z "${fgfs_args[(r)--igc=*]}" ]]; then
        fgfs_args+=(--igc=file,out,1,$(date +%Y%m%d-%H%M-${${${fgfs_args[(r)--aircraft=*]}#--aircraft=}:-$(sed -rn 's|^.+aircraft>(.+)</aircraft.+$|\1|p' $FGDIR/source/fgdata/defaults.xml)}.igc))
    fi

    ld_library_path

    echo ${fgfs_args[@]}
# TODO: ne lancer avec primusrun que si c'est nécesaire, d'autres solution existent ?
    primusrun $FGDIR/install/flightgear/bin/fgfs ${fgfs_args[@]}
    
    if grep -q $HOME/.fgfs/terrafs.d /proc/mounts; then
        fusermount -u $HOME/.fgfs/terrafs.d
    fi
    unset fgfs_args
}