167 lines
4.2 KiB
Bash
Executable File
167 lines
4.2 KiB
Bash
Executable File
#!/bin/bash
|
|
#
|
|
# list_apps_in_pkg
|
|
#
|
|
|
|
###
|
|
### settings
|
|
###
|
|
|
|
set -e # exit on any uncaught error
|
|
set +o histexpand # don't expand history expressions
|
|
shopt -s nocasematch # case-insensitive regular expressions
|
|
|
|
###
|
|
### global variables
|
|
###
|
|
|
|
opt_lax=''
|
|
opt_pkg=''
|
|
pkgdir=''
|
|
|
|
# prefer GNU xargs
|
|
xargs="$(/usr/bin/which gxargs || printf '/usr/bin/xargs')"
|
|
|
|
###
|
|
### functions
|
|
###
|
|
|
|
warn () {
|
|
local message="$@"
|
|
message="${message//\\t/$'\011'}"
|
|
message="${message//\\n/$'\012'}"
|
|
message="${message%"${message##*[![:space:]]}"}"
|
|
printf "%s\n" "$message" 1>&2
|
|
}
|
|
|
|
die () {
|
|
warn "$@"
|
|
exit 1
|
|
}
|
|
|
|
app_source_1 () {
|
|
/usr/bin/find "$pkgdir" -name PackageInfo -print0 | \
|
|
"$xargs" -0 /usr/bin/perl -0777 -ne \
|
|
'while (m{<pkg-info[^\n]*install-location="/Applications".*?path\s*=\s*"([^"]+)"}sg) { my $p = $1; $p =~ s{\A.*/}{}; print "$p\n" }';
|
|
}
|
|
|
|
app_source_2 () {
|
|
/usr/bin/find "$pkgdir" -name PackageInfo -print0 | \
|
|
"$xargs" -0 /usr/bin/perl -0777 -ne \
|
|
'while (m{<pkg-info[^\n]*install-location="/".*?path\s*=\s*"./Applications/([^"]+)"}sg) { my $p = $1; $p =~ s{\A.*/}{}; print "$p\n" }';
|
|
}
|
|
|
|
app_source_3 () {
|
|
/usr/bin/find "$pkgdir" -type d -name '*.app' | \
|
|
perl -pe 's{\A.*/}{}';
|
|
}
|
|
|
|
app_source_4 () {
|
|
/usr/bin/find "$pkgdir" -name PackageInfo -print0 | \
|
|
"$xargs" -0 /usr/bin/perl -0777 -ne \
|
|
'while (m{path\s*=\s*"([^"]+\.app)"}sg) { my $p = $1; $p =~ s{\A.*/}{}; print "$p\n" }';
|
|
}
|
|
|
|
app_source_5 () {
|
|
/usr/bin/find "$pkgdir" -name Archive.pax.gz -print0 | \
|
|
"$xargs" -0 -n1 -I{} /bin/bash -c \
|
|
"/usr/bin/gunzip -c '{}' | /bin/pax | /usr/bin/egrep '\.app'" | \
|
|
/usr/bin/perl -pe 's{\A.*/([^/]+\.app).*\Z}{$1}';
|
|
}
|
|
|
|
merge_sources () {
|
|
/usr/bin/sort | /usr/bin/uniq
|
|
}
|
|
|
|
mark_up_sources () {
|
|
/usr/bin/perl -pe 's{\n}{\000}sg' | \
|
|
"$xargs" -0 -I{} -n1 /bin/bash -c \
|
|
'printf "{}"; /bin/test -n "$(/usr/bin/find /Applications -type d -maxdepth 3 -name "{}" -print0; /usr/bin/find ~/Applications -type d -maxdepth 3 -name "{}")" && printf " (+)"; printf "\n"'
|
|
}
|
|
|
|
process_args () {
|
|
local arg
|
|
if [[ "$#" -eq 0 ]]; then
|
|
die "ERROR: A file argument is required"
|
|
else
|
|
opt_pkg="${!#}" # last arg
|
|
fi
|
|
for arg in "$@"; do
|
|
if [[ $arg =~ ^-+h(elp)?$ ]]; then
|
|
printf "list_apps_in_pkg [ -lax ] <file.pkg>
|
|
|
|
Given a package file, extract a list of candidate App names from
|
|
inside the pkg, which may be useful for naming a Cask.
|
|
|
|
The given package file need not be installed.
|
|
|
|
If an App of the listed name is already installed in /Applications
|
|
or ~/Applications, it will be followed by a plus symbol '(+)' in
|
|
the output. This can be verified via 'ls' or the Finder.
|
|
|
|
Arguments
|
|
|
|
-lax Be less selective in looking for App names. Generate
|
|
more, but less accurate, guesses.
|
|
|
|
Bugs: This script is imperfect.
|
|
- It does not fully parse PackageInfo files
|
|
- An App can be hidden within a nested archive and not found
|
|
- Some pkg files simply don't contain any Apps
|
|
|
|
See CONTRIBUTING.md and 'man pkgutil' for more information.
|
|
|
|
"
|
|
exit
|
|
elif [[ $arg =~ ^-+lax$ ]]; then
|
|
opt_lax='true'
|
|
elif [[ "$arg" = "$opt_pkg" ]]; then
|
|
true
|
|
else
|
|
die "ERROR: Unknown argument '$arg'"
|
|
fi
|
|
done
|
|
if [[ -h "$opt_pkg" ]]; then
|
|
opt_pkg="$(/usr/bin/readlink "$opt_pkg")"
|
|
fi
|
|
if ! [[ -e "$opt_pkg" ]]; then
|
|
die "ERROR: No such pkg file: '$opt_pkg'"
|
|
fi
|
|
}
|
|
|
|
###
|
|
### main
|
|
###
|
|
|
|
_list_apps_in_pkg () {
|
|
|
|
if [[ -d "$opt_pkg" ]]; then
|
|
pkgdir="$opt_pkg"
|
|
else
|
|
local tmpdir="$(/usr/bin/mktemp -d -t list_ids_in_pkg)"
|
|
trap "/bin/rm -rf -- '$tmpdir'" EXIT
|
|
pkgdir="$tmpdir/unpack"
|
|
/usr/sbin/pkgutil --expand "$opt_pkg" "$tmpdir/unpack" "$pkgdir"
|
|
fi
|
|
|
|
{
|
|
# strings that look like App names (Something.app)
|
|
app_source_1;
|
|
app_source_2;
|
|
app_source_3;
|
|
if [[ -n "$opt_lax" ]]; then
|
|
app_source_4;
|
|
app_source_5;
|
|
fi
|
|
} | \
|
|
merge_sources | \
|
|
mark_up_sources
|
|
}
|
|
|
|
process_args "${@}"
|
|
|
|
# dispatch main
|
|
_list_apps_in_pkg
|
|
|
|
#
|