-
Notifications
You must be signed in to change notification settings - Fork 14
/
Copy patheix-installed-after.sh.in
executable file
·255 lines (232 loc) · 8.31 KB
/
eix-installed-after.sh.in
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
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
#!/usr/bin/env sh
# This script is part of the eix project and distributed under the
# terms of the GNU General Public License v2.
#
# Authors and Copyright (c):
# Martin V\"ath <[email protected]>
#
# This script lists all packages installed after/before a certain package
# See the eix manpage for details. (@PACKAGE_STRING@).
set -u
# We make use of the functions provided by eix-functions.sh:
if eix_funcs=`./eix-functions.sh.in 2>/dev/null`
then eval "$eix_funcs"
else echo "${0##*/}: cannot find eix-functions.sh" >&2
exit 1
fi
ReadFunctions
# Prepend content of eix variable EIX_INSTALLED_AFTER to the arguments
ReadVar EIX_INSTALLED_AFTER
eval "set -- a $EIX_INSTALLED_AFTER \${1+\"\$@\"}"
shift
# The following function outputs the usage of the script and then dies.
Usage() {
n=${0##*/}
p='@PACKAGE_STRING@'
eval_gettext 'Usage: ${n} [options] category/package[:slot]
This is a well-commented demo script for eix (${p}).
It lists packages installed after (or before) the last (or first) install
of the given package/version in an output format which is convenient
as an argument for "emerge -1".
Be aware that only packages in the eix database are considered.
The argument can use shell pattern matching (* and ?; do not forget to quote
them if you call this script from a shell); the first match is chosen.
The :slot part can be omitted if the corresponding package has only one slot.
(Options -l and -L have different rules.)
The argument is not needed if option -f, -e or -F is used.
The eix (or environment) variable EIX_INSTALLED_AFTER is prepended to the
arguments; note that this variable is evaluated, so quote properly and be
aware about security risks!
The following options are available:
-i Ignore all previous options (useful if EIX_INSTALLED_AFTER is set.)
-f Output full list of all packages.
-e TIME Use TIME as "install" date.
TIME is in seconds since epoch (see e.g. "date +%s")
-F FILE Use the mtime of FILE as the "install" date.
-l Use /var/log/emerge.log to use the _first_ (instead of the last) install
time of the given package. In this case, the argument must be a
regular expression matching category/package-version.
Note that the time in the log file and the time recorded in the database
usually differ slightly so that usage/non-usage of option -I need not
have the expected effect: The package may or may not be included.
You can use -a/-A to fix the time. Note also that -t or -T have no
effect on the data in the log file.
-L LOG As -l but use LOG instead of /var/log/emerge.log
-a SEC With -F, -l -L, or -e, increase the actual match time by SEC seconds.
-A SEC With -F, -l -L, or -e, decrease the actual match time by SEC seconds.
-b Output packages installed before (instead of after) the given package
-I Include the given package (on the command line) in the output
-S When finding the starting package, choose the first matching slot
-V When finding the starting package, look for category/package-version
instead of category/package:slot
-d Output the installation date after the package
-s Output slot of the package, even if there appears no ambiguity
-v Output category/package-version instead of category/package[:slot]
-= Output =category/package-version instead of category/package[:slot]
-t Use build time (if available) instead of installation time,
independent of the value of USE_BUILD_TIME
-T Never use build time'
echo
exitcode=${1:-1}
Exit $exitcode
}
# Parse the command line options:
DefaultOpts() {
full=false
timefile=
epoch=
logfile=
before=false
date_output=
output='NAMESLOT'
input='NAMESLOT'
including=false
addtime=
subtime=
}
DefaultOpts
OPTIND=1
while getopts 'fF:lL:e:a:A:bdsv=SViItTh' opt
do case $opt in
f) full=:;;
F) timefile=$OPTARG;;
l) logfile='/var/log/emerge.log';;
L) logfile=$OPTARG;;
e) epoch=$OPTARG;;
a) addtime=$OPTARG;;
A) subtime=$OPTARG;;
b) before=:;;
d) date_output='\t<date:DATE_OUTPUT>';;
s) output='NAMEASLOT';;
v) output='NAMEVERSION';;
'=') output='EQNAMEVERSION';;
S) input='NAME';;
V) input='NAMEVERSION';;
i) DefaultOpts;;
I) including=:;;
t) USE_BUILD_TIME=true; export USE_BUILD_TIME;;
T) USE_BUILD_TIME=false; export USE_BUILD_TIME;;
'?') exitcode=1; Exit 1;;
*) Usage 0;;
esac
done
[ $OPTIND -le 1 ] || shift `Expr $OPTIND - 1`
# After the options there should be exactly one argument: $match
if [ -n "${timefile:++}" ]
then epoch=`stat -c '%Y' -- "$timefile" 2>/dev/null` || epoch=
fi
# "found" is our flag in the loop whether we already found our package.
found=false
if $full
then logfile=
before=false
epoch=
found=:
elif [ -z "${epoch:++}" ]
then [ $# -eq 1 ] || Usage
match=$1
fi
# With options -l or -L, we also have to parse the logfile:
if [ -n "${logfile:++}" ]
then test -r "$logfile" || die "`eval_gettext 'cannot read ${logfile}'`"
epoch=`unset LC_ALL
LC_COLLATE=C
sed -ne "\\: Merging ($match\\:\\:.*):{s/^\([0-9]*\).*/\\1/p
q}" "$logfile"` && [ -n "${epoch:++}" ] || die "`eval_gettext \
'cannot find merge of ${match} in ${logfile}'`"
fi
# We will let eix output for each installed package (and then sort by time):
# date (in the format %s) TAB
# package (in the input format) TAB
# package (in the output format) [TAB date (in the format "%x %X")]
# newline
# (the [...] part occurs only with option -d).
# The functions Check resp. Output are called with each $line as argument
# (which thus undergoes the usual splitting at spaces or tabs).
# Check returns 0 if the package matches $match (or is known to be younger).
# Output outputs the package (and date).
# Both functions ignore empty lines.
if [ -z "${epoch:++}" ]
then
Check() {
[ $# -ge 2 ] && case "$2:" in
$match:*)
return 0;;
esac
return 1
}
else [ -z "${addtime:++}" ] || epoch=`Expr "$epoch" + "$addtime"`
[ -z "${subtime:++}" ] || epoch=`Expr "$epoch" - "$subtime"`
# With options -f, -e, -l, -L, we need a different Check function:
Check() {
[ $# -ne 0 ] && [ "$1" -ge "$epoch" ]
}
fi
Output() {
if [ $# -eq 3 ]
then Echo "$3"
elif [ $# -gt 3 ]
then printf '%-43s %-11s %s\n' "$3" "$4" "$5"
fi
}
# Now the main loop. The interesting point is of course the call to eix.
#
# We could define NAMESLOT, NAMEASLOT, NAMEVERSION, and EQNAMEVERSION
# instead of using their default definitions (which are built into eix).
# However, we want to allow that the user overrides these definitions if he
# wants to and thus is able to change the input/output format of this script
# implicitly.
#
# Since there is no corresponding default variable which outputs _only_
# the package category/name (and never the slot), we define such a variable
# for option -S (we have chosen the name NAME for that).
#
# As you can see with "eix --dump", the default definitions of
# NAMESLOT, NAMEASLOT, NAMEVERSION, and EQNAMEVERSION make use of the variable
# VERSION_NEWLINE to output an optional newline.
# We do not want such a newline: In fact, the only newline we want is the one
# which should be output at the end of the LINE variable.
# So we set VERSION_NEWLINE=
#
# We set NOCOLORS to avoid the "reset color string" at the very end.
#
# We set EIX_LIMIT to 0 to force output of really all packages.
#
# To define the output format, we use the --format argument.
# If we would have used the FORMAT variable instead (or in <eix-0.29.6)
# we would have to set additionally DEFAULT_FORMAT=normal to make sure
# the a user's setting of DEFAULT_FORMAT is overridden.
#
# The --format refers implicitly to the LINE variable which in turn refers
# implicitly to DATE_FORMAT, DATE_OUTPUT, and NAME:
#
# The name of the variables DATE_FORMAT, DATE_OUTPUT, NAME, and LINE
# could also be any other unused names; it is only important that in LINE
# resp. in the --FORMAT argument we use the corresponding variable names.
#
# We have to quote \ for the shell when we use "..." to set variables.
#
# Note that all the following variables are automatically exported, since
# they immediately preceed the command (the \ at the line-ends is crucial):
NOCOLORS=: \
EIX_LIMIT=0 \
VERSION_NEWLINE= \
DATE_FORMAT='%s' \
DATE_OUTPUT='%x %X' \
NAME='<category>/<package>' \
LINE='<date:DATE_FORMAT>\t%{'$input'}\t%{'$output'}'$date_output'\n' \
eix --format '<installedversions:LINE>' '-I*sb' \
| sort -n \
| {
while read -r line
do if $found
then $before || Output $line
elif Check $line
then found=:
$including && Output $line
else $before && Output $line
fi
done
$found
}
Exit