OSDN Git Service

059f859c55d882d622029841888f4dbad795d3ea
[alterlinux/aptpac.git] / aptpac
1 #!/usr/bin/env bash
2 #
3 #               __
4 #              /\ \__
5 #   __    _____\ \ ,_\ _____     __      ___
6 # /'__`\ /\ '__`\ \ \//\ '__`\ /'__`\   /'___\
7 #/\ \L\.\\ \ \L\ \ \ \\ \ \L\ /\ \L\.\_/\ \__/
8 #\ \__/.\_\ \ ,__/\ \__\ \ ,__\ \__/.\_\ \____\
9 # \/__/\/_/\ \ \/  \/__/\ \ \/ \/__/\/_/\/____/
10 #           \ \_\        \ \_\
11 #            \/_/         \/_/
12 # a pacman wrapper with syntax based on debian's apt
13 # (c) 2019-2020 Fascode Network.
14 # License: Do What The Fuck You Want To Public License
15 # maintained by Yamada Hayao
16
17 # Enter the path to the AUR helper you want to use here. 
18 # If it is empty, the corresponding AUR helper will be searched automatically.
19 #AURHELPER=
20
21 set -e
22
23
24 # APTPAC Version
25 APTPAC_VERSION="3.3.0"
26
27 # Initilize List
28 PACMAN_PACKAGE_FILE=()
29 PACMAN_PACKAGE=()
30 DEB_PACKAGE_FILE=()
31
32 # PACMAN Config
33 HELPERS=(
34     "/usr/bin/yay"
35     "/usr/bin/paru"
36     "/usr/bin/yaourt"
37     "/usr/bin/aurman"
38     "/usr/bin/pikaur"
39     "/usr/bin/pacaur"
40     "/usr/bin/aura"
41     "/usr/bin/wfa"
42 )
43 PACMAN_OPTIONS=()
44 DEFAULT_PACMAN_COMMAND="/usr/bin/pacman"
45 PACMAN_COMMAND="${DEFAULT_PACMAN_COMMAND}"
46 PACMAN_CONFIG="/etc/pacman.conf"
47
48 # APTPAC Config
49 DEBTAP_WORK="/tmp/aptpac-debtap"
50 DEBUG=false
51 RUN_WITH_SUDO=false
52 DIRECT_PACMAN=false
53 AUTOREMOVE=false
54 INSTALL=false
55
56 _msg_error () {
57     echo -e "${@}" >&2
58 }
59
60 _msg_debug () {
61     if "${DEBUG}"; then
62         echo -e "${@}" >&1
63     fi
64 }
65
66
67 # List option
68 INSTALLED_PKGLIST=false
69
70 _usage () {
71     echo "usage ${0} [options] [command] [packages]"
72     echo
73     echo " apt commands:"
74     echo "    install                              Install the specified package"
75     echo "    remove                               Remove the specified package"
76     echo "    purge                                Permanently remove the package"
77     echo "    update                               Update package database"
78     echo "    upgrade | full-upgrade               Update packages"
79     echo "    edit-sources                         Edit config file of pacman"
80     echo "    search                               Search for a package"
81     echo "    autoremove                           Remove unnecessary packages"
82     echo "    clean                                Remove the package cache"
83     echo "    list                                 Display a list of packages"
84     echo "    show | showpkg                       Display the package records"
85     echo "    rdepends                             Display the dependencies"
86     echo
87     echo " apt options:"
88     echo "    -y | --yes  | --assume-yes           Do not check"
89     echo "    -d | --download-only                 Only download the package"
90     echo "    -c | --config-file <file>            Config file for pacman"
91     echo "    -h | --help                          Display this help"
92     echo "    -v | --version                       Display the version of aptpac and pacman"
93     echo "         --auto-remove | --autoremove    Remove unnecessary packages with other command"
94     echo "         --purge                         Delete the entire configuration file"
95     echo
96     echo " pacapt options:"
97     echo "         --aur-helper <command>          Specifies the command to use as the AUR helper"
98     echo "                                         Ignored if pacapt is run as root"
99     echo "                                         Specify AUR helper that supports common command line options with pacman"
100     echo
101     echo " Notes:"
102     echo "    - aptpac supports not only above options but also options of pacman"
103     echo "    - If you specify the deb file, you can install using debtap"
104 }
105
106 _exit () {
107     exit "${1}"
108 }
109
110 _version () {
111 cat << EOF
112 aptpac ${APTPAC_VERSION} - A pacman wrapper with syntax based on debian's apt
113 License: Do What The Fuck You Want To Public License
114 (c) 2019-2020 Fascode Network. Yamada Hayao
115 EOF
116     echo
117     pacman --version
118 }
119
120 ADD_OPTION () {
121     PACMAN_OPTIONS+=("${@}")
122 }
123
124 _sudo(){
125     if "${RUN_WITH_SUDO}"; then
126         eval sudo "${@}"
127     else
128         eval "${@}"
129     fi
130 }
131
132 _pacman(){
133     _sudo "${PACMAN_COMMAND}" "${PACMAN_OPTIONS[@]}" --config "${PACMAN_CONFIG}" "${@}"
134 }
135
136 _run_detect_aur_helper(){
137     if [[ ! "${UID}" = 0 ]]; then
138         if [[ -z "${AURHELPER+SET}" ]]; then
139             for AURHELPER in "${HELPERS[@]}"; do
140                 if [[ -f "${AURHELPER}" ]]; then
141                     PACMAN_COMMAND="${AURHELPER}"
142                     break
143                 elif hash "$(basename "${AURHELPER}")" 2> /dev/null; then
144                     PACMAN_COMMAND="$(basename "${AURHELPER}")"
145                     break
146                 fi
147             done
148         else
149             if [[ -f "${AURHELPER}" ]]; then
150                 PACMAN_COMMAND="${AURHELPER}"
151             elif hash "$(basename "${AURHELPER}")" 2> /dev/null; then
152                 PACMAN_COMMAND="$(basename "${AURHELPER}")"
153             else
154                 _msg_error "${AURHELPER} is not installed"
155                 exit 1
156             fi
157         fi
158     fi
159 }
160
161 _run_aur_message(){
162     if [[ ! "${PACMAN_COMMAND}" = "${DEFAULT_PACMAN_COMMAND}" ]] && [[ ! "$(basename "${PACMAN_COMMAND}")" = "$(basename "${DEFAULT_PACMAN_COMMAND}")" ]]; then
163         _msg_debug "Use AUR helper ${PACMAN_COMMAND}"
164     else
165         RUN_WITH_SUDO=true
166     fi
167 }
168
169 _run_autoremove(){
170     if "${AUTOREMOVE}"; then
171         if [[ -n $(${PACMAN_COMMAND} -Qttdq) ]]; then
172             "${PACMAN_COMMAND}" -Qttdq | _sudo "${PACMAN_COMMAND}" -Rsc --config "${PACMAN_CONFIG}" -
173         else
174             echo "No packages to remove"
175             exit 0
176         fi
177     fi
178 }
179
180 _run_distinguish_package(){
181     local pkg
182     for pkg in "${PACKAGE[@]}"; do
183         if [[ ! -f "${pkg}" ]]; then
184             PACMAN_PACKAGE+=("${pkg}")
185         elif [[ "$(file -b --mime-type "${pkg}" 2> /dev/null)" = "application/vnd.debian.binary-package" ]]; then
186             DEB_PACKAGE_FILE+=("${pkg}")
187         else
188             PACMAN_PACKAGE_FILE+=("${pkg}")
189         fi
190     done
191 }
192
193 _run_pacman(){
194     if [[ "${INSTALL}" = true ]]; then
195         _pacman -S "${PACMAN_PACKAGE[@]}"
196     else
197         _pacman "${PACMAN_PACKAGE[@]}"
198     fi
199 }
200
201 _run_debtap(){
202     if (( "${#DEB_PACKAGE_FILE[@]}" != 0 )) && ! hash "debtap"; then
203         _msg_error "debtap was not found"
204         exit 1
205     fi
206
207     if [[ -z "$(find "/var/cache/pkgfile" -maxdepth 1 -mindepth 1 -name "*.files" 2> /dev/null)" ]] || [[ -z "$(find "/var/cache/debtap" -maxdepth 1 -mindepth 1 -name "*-packages" 2> /dev/null)" ]] || [[ -z "$(find "/var/cache/debtap" -maxdepth 1 -mindepth 1 -name "*-files" 2> /dev/null)" ]]; then
208         sudo debtap -u
209     fi
210
211     (
212         sudo mkdir -p "${DEBTAP_WORK}"
213         local pkg work
214         for pkg in "${DEB_PACKAGE_FILE[@]}"; do
215             work="${DEBTAP_WORK}/$(basename "${pkg}")/"
216             file="${work}/$(basename "${pkg}")"
217             sudo mkdir -p "${work}"
218             cd "${work}"
219             sudo cp "${pkg}" "${file}"
220             sudo debtap --Quiet "${file}"
221             while read -r archpkg; do
222                 _pacman -U "${archpkg}"
223             done < <(find "${work}" -maxdepth 1 -mindepth 1 -type f -name "*.pkg.tar.*")
224         done
225     )
226 }
227
228
229 # Argument analysis and processing
230 set +e
231 PACAPT_ARGUMENTS=("${@}")
232 _opt_short="ydfc:hvVDFQRSTU"
233 _opt_long="yes,assume-yes,download-only,fix-broken,purse,installed,debug,help,version,config-file:,auto-remove,autoremove,aur-helper:,pflags:"
234 OPT=$(getopt -o ${_opt_short} -l ${_opt_long} -- "${@}" 2> /dev/null)
235 set -e
236 #if [[ ${?} != 0 ]]; then
237 #    exit 1
238 #fi
239
240 eval set -- "${OPT}"
241 #echo "Argument is \"${OPT}\""
242 unset OPT _opt_short _opt_long
243
244 while true; do
245     case "${1}" in
246         -y | --yes | --assume-yes)
247             ADD_OPTION "--noconfirm"
248             shift 1
249             ;;
250         -d | --download-only)
251             ADD_OPTION "-w"
252             shift 1
253             ;;
254         -f | --fix-broken)
255             shift 1
256             ;;
257         -c | --config-file)
258             PACMAN_CONFIG="${2}"
259             shift 2
260             ;;
261         --purge)
262             ADD_OPTION "-n"
263             shift 1
264             ;;
265         --installed)
266             INSTALLED_PKGLIST=true
267             shift 1
268             ;;
269         --debug)
270             DEBUG=true
271             shift 1
272             ;;
273         -h | --help)
274             _usage
275             shift 1
276             exit 0
277             ;;
278         -v | --version)
279             _version
280             shift 1
281             exit 0
282             ;;
283         --autoremove | --auto-remove)
284             AUTOREMOVE=true
285             shift 1
286             ;;
287         --aur-helper)
288             if [[ ! "${UID}" = 0 ]] && [[ -f "${2}" ]]; then
289                 PACMAN_COMMAND="${2}"
290             elif [[ "${UID}" = 0 ]]; then
291                 _msg_warn "The specified AUR helper is not used because pacapt is running on the root."
292             elif hash "$(basename "${2}")" 2> /dev/null; then
293                 PACMAN_COMMAND="$(basename "${2}")"
294             else
295                 _msg_error "${2} is not installed"
296                 exit 1
297             fi
298             shift 2
299             ;;
300         --pflags)
301             # shellcheck disable=SC2086
302             ADD_OPTION ${2}
303             shift 2
304             ;;
305         -V | -D | -F | -Q | -R | -S | -T | -U)
306             DIRECT_PACMAN=true
307             ADD_OPTION "${PACAPT_ARGUMENTS[@]}"
308             break
309             ;;
310         --)
311             shift 1
312             break
313             ;;
314         *)
315             _msg_error "Invalid argument '${1}'"
316             _help
317             exit 1
318             ;;
319     esac
320 done
321
322 if [[ "${DIRECT_PACMAN}" = false ]]; then
323     if [[ $# -lt 1 ]]; then
324         _msg_error "No command specified"
325         _usage
326         _exit 1
327     fi
328     COMMAND="${1,,}"
329
330     shift 1
331
332     PACKAGE=("${@}")
333
334     case "${COMMAND}" in
335         install)
336             #ADD_OPTION "-S"
337             INSTALL=true
338             ;;
339         remove)
340             ADD_OPTION "-Rsc"
341             ;;
342         purge)
343             ADD_OPTION "-Rsnc"
344             ;;
345         update)
346             ADD_OPTION "-Syy"
347             ;;
348         upgrade)
349             ADD_OPTION "-Syu"
350             ;;
351         search)
352             ADD_OPTION "-Ss"
353             ;;
354         full-upgrade)
355             ADD_OPTION "-Syu"
356             ;;
357         clean)
358             ADD_OPTION "-Sccc"
359             ;;
360         dist-upgrade)
361             ADD_OPTION "-Syu"
362             ;;
363         edit-sources)
364             if [[ -n "${EDITOR}" ]]; then
365                 sudo "${EDITOR}" "${PACMAN_CONFIG}"
366             else
367                 sudo nano "${PACMAN_CONFIG}"
368             fi
369             _exit 0
370             ;;
371         huawei) 
372             if [[ "$(source "/etc/locale.conf" 2> /dev/null; echo -n "${LANG}")" = "ja_JP.UTF-8" ]]; then
373                 echo "(ง •ᴗ•)ว ⁾⁾ファーウェイでウェイウェイ"
374                 _exit 0
375             else
376                 _msg_error "Invalid command '${COMMAND}'"
377                 _exit 1
378             fi
379             ;;
380         moo)
381             echo "         (__) "
382             echo "         (oo) "
383             echo "   /------\/ "
384             echo "  / |    ||   "
385             echo " *  /\---/\ "
386             echo "    ~~   ~~   "
387             echo "....\"Have you mooed today?\"..."
388             exit 0
389             ;;
390         autoremove) 
391             if [[ -n "$(${PACMAN_COMMAND} -Qttdq)" ]]; then
392                 ADD_OPTION "-Rsc"
393                 while read -r pkg; do
394                     PACKAGE+=("${pkg}")
395                 done < <(${PACMAN_COMMAND} -Qttdq)
396             else
397                 echo "No packages to remove"
398                 exit 0
399             fi
400             ;;
401         list)
402             if [[ "${INSTALLED_PKGLIST}" = true ]]; then
403                 ADD_OPTION "-Q | grep"
404             else
405                 ADD_OPTION "-Ss"
406             fi
407             ;;
408         show | showpkg)
409             for pkg in "${PACKAGE[@]}"; do
410                 if pacman -Qq "${pkg}" 2> /dev/null 1>&2; then
411                     "${PACMAN_COMMAND}" "${PACMAN_OPTIONS[@]}" -Qi --config "${PACMAN_CONFIG}" "${pkg}"
412                 else
413                     "${PACMAN_COMMAND}" "${PACMAN_OPTIONS[@]}" -Si --config "${PACMAN_CONFIG}" "${pkg}"
414                 fi
415             done
416             unset pkg
417             _exit 0
418             ;;
419         rdepends)
420             ADD_OPTION "-Sii"
421             ;;
422         help)
423             _usage
424             exit 0
425             ;;
426         *)
427             _msg_error "Invalid command '${COMMAND}'"
428             _exit 1
429             ;;
430     esac
431 fi
432
433
434 _run_detect_aur_helper
435 _run_aur_message
436 _run_distinguish_package
437 _run_pacman
438 if [[ "${INSTALL}" = true ]]; then
439     _run_debtap  
440 fi
441 _run_autoremove