aboutsummaryrefslogtreecommitdiffstats
path: root/sti
blob: f89a9c19c9dd5e26e72850f98c6295f818b0394e (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
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
#!/bin/bash
# sti --- Stupid Tool Installer
# Copyright (C) 2014  Tom Willemse <tom@ryuslash.org>

# sti is free software: you can redistribute it and/or modify it under
# the terms of the GNU General Public License as published by the Free
# Software Foundation, either version 3 of the License, or (at your
# option) any later version.

# sti is distributed in the hope that it will be useful, but WITHOUT
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
# or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
# License for more details.

# You should have received a copy of the GNU General Public License
# along with sti.  If not, see <http://www.gnu.org/licenses/>.

_sti_executable="$(basename $0)"
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 init
{
    for exe in $(find-executables "$1"); 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
}

function uninit
{
    for exe in $(find-executables "$1"); 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
}

function help_help { cmd_help "$@"; }
function cmd_help
{
    if [[ -n "$1" ]]; then
        local prefix="help"
        dispatch "$@"
    else
        echo "Usage: ${_sti_executable} <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 "  update   Update an installed tool"
        echo
        echo "You can use \`${_sti_executable} help <command>' to get \
more information about a command." | fold
    fi
}

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

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

function help_reinit ()
{
    echo "Usage: ${_sti_executable} reinit TOOL"
    echo
    echo "TOOL should be the name of a tool installed previously with \
\`${_sti_executable} 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
        init "$tool_home"
    fi
}

function help_install ()
{
    echo "Usage: ${_sti_executable} 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"
        init "$tool_home"
    else
        echo "Tool ${tool_name} already installed"
        exit 2
    fi
}

function help_remove ()
{
    echo "Usage: ${_sti_executable} remove TOOL"
    echo
    echo "TOOL should be the name of a tool installed previously with \
\`${_sti_executable} 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
        uninit "$tool_home"
        rm -rf "$tool_home" && echo "Succesfully removed $1"
    else
        echo "Tool $1 is not installed"
        exit 2
    fi
}

function help_update
{
    echo "Usage: ${_sti_executable} update TOOL"
    echo
    echo "TOOL should be the name of a tool installed previously with \
\`${_sti_executable} install'. This name is the base name of the URL \
used to install the tool, with the \`.git' suffix removed." | fold
    echo
    echo "This command removes all the executables from \`${data_home}' \
just as \`${_sti_executable} remove' would, calls \`git pull' in TOOL's \
directory and then reinstalls the executables as \`${_sti_executable} \
reinit' would."
}

function cmd_update
{
    tool_home="${data_home}/tools/$1"

    if [[ -d "$tool_home" ]]; then
        uninit "$tool_home"
        cd $tool_home && git pull
        init "$tool_home"
    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