aboutsummaryrefslogtreecommitdiffstats
path: root/sti
blob: 7247e0604e472f81acd16188f39ea502b0be3c1b (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
#!/bin/bash
# sti --- Stupid Tool Installer

data_home="${XDG_DATA_HOME:-${HOME}/.local/share}/sti"
bin_home="${HOME}/usr/bin"

function fold () { /usr/bin/fold -s -w $(tput cols); }
function find-executables ()
{
    find "$1" -type f -executable \! -wholename "${data_home}/*/.*"
}

function help_help { cmd_help "$@"; }
function cmd_help
{
    local xname="$(basename $0)"

    if [[ -n "$1" ]]; then
        local prefix="help"
        dispatch "$@"
    else
        echo "Usage: $xname <command> ARG"
        echo
        echo "Commands include: "
        echo "  help     Show this help message"
        echo "  install  Install a tool from a git repository"
        echo "  list     List downloaded tools"
        echo "  reinit   Retry installing the executables of a tool"
        echo "  remove   Remove an installed tool"
        echo
        echo "You can use \`$xname help <command>' to get more \
information about a command." | fold
    fi
}

function help_list ()
{
    local xname="$(basename $0)"

    echo "Usage: ${xname} list"
    echo
    echo "List all downloaded (possibly installed) tools." | fold
}

function cmd_list
{
    /usr/bin/ls -1 "${data_home}/tools/"
}

function help_reinit ()
{
    local xname="$(basename $0)"

    echo "Usage: ${xname} reinit TOOL"
    echo
    echo "TOOL should be the name of a tool installed previously with \
\`${xname} install'. This name is the base name of the URL used to \
install the tool, with the \`.git' suffix removed." | fold
    echo
    echo "Each executable file found in the tool's directory is checked \
to see if it exists in ${bin_home}, it reports whether it is already \
installed or doesn't belong to the tool. If it doesn't exist a symlink \
is created in ${bin_home}." | fold
}

function cmd_reinit ()
{
    local tool_home="${data_home}/tools/$1"

    if [[ -d "$tool_home" ]]; then
        for exe in $(find-executables "$tool_home"); do
            local executable_name=$(basename "$exe")
            local destination="${bin_home}/${executable_name}"

            if [[ ! -e "$destination" ]]; then
                ln -s "$exe" "$destination"
            elif [[ "$(readlink $destination)" == "$exe" ]]; then
                echo "Executable ${executable_name} already installed"
            else
                echo "Executable ${executable_name} already exists in \
${bin_home}"
            fi
        done
    fi
}

function help_install ()
{
    local xname="$(basename $0)"

    echo "Usage: ${xname} install URL"
    echo
    echo "URL should be a valid argument to \`git clone'."
    echo
    echo "URL is cloned and for each executable file found in the \
resulting directory a symlink is created in ${bin_home}. If there is \
already a file with the same name, no symlink is created and a message \
is displayed." | fold
}

function cmd_install ()
{
    tool_name=$(basename $1 .git)
    tool_home="${data_home}/tools/${tool_name}"

    # Ensure the bin directory exists.
    if [[ ! -d "$bin_home" ]]; then
        echo "Creating directory ${bin_home}"
        mkdir -p "$bin_home"
    fi

    if [[ ! -d "$tool_home" ]]; then
        git clone $1 "$tool_home"
        cmd_reinit "$tool_name"
    else
        echo "Tool ${tool_name} already installed"
        exit 2
    fi
}

function help_remove ()
{
    local xname="$(basename $0)"

    echo "Usage: ${xname} remove TOOL"
    echo
    echo "TOOL should be the name of a tool installed previously with \
\`${xname} install'. This name is the base name of the URL used to \
install the tool, with the \`.git' suffix removed." | fold
    echo
    echo "Any executable files found in the directory of TOOL will have \
their symlinks in ${bin_home} removed. If a file exists with the same \
name as one of the symlinks should have and it is not a symlink to one \
of TOOL's executables, it is not removed and a message is displayed." \
    | fold
}

function cmd_remove ()
{
    tool_home="${data_home}/tools/$1"

    if [[ -d "$tool_home" ]]; then
        for exe in $(find-executables "$tool_home"); do
            local real_path=$(realpath "$exe")
            local base_name=$(basename "$exe")
            local link_path="${bin_home}/${base_name}"
            local linked_path=$(readlink "$link_path")

            if [[ -e "$link_path" ]] \
               && [[ "$linked_path" == "$real_path" ]]; then
                rm "$link_path"
            else
                echo "Executable ${base_name} is not part of $1"
            fi
        done
        rm -rf "$tool_home" && echo "Succesfully removed $1"
    else
        echo "Tool $1 is not installed"
        exit 2
    fi
}

function dispatch
{
    local name="${prefix-cmd}_$1"

    if [[ $(type -t "$name") == "function" ]]; then
        shift
        "$name" "$@"
    else
        echo "Unknown command: $1"
        exit 1
    fi
}

if [[ ${#@} -lt 1 ]]; then
    cmd_help "$@"
    exit 1
else
    dispatch "$@"
fi