mirror of
https://github.com/lloeki/apply.git
synced 2025-12-06 09:24:38 +01:00
lib: add user_homedir and sponge functions
This commit is contained in:
parent
e0d5017c98
commit
a67fa4f250
2 changed files with 102 additions and 0 deletions
59
lib
59
lib
|
|
@ -80,3 +80,62 @@ epochseconds() {
|
|||
# TODO(andrew-d): break down and verify the math here
|
||||
echo $(( $(TZ=GMT0 date +"((%Y-1600)*365+(%Y-1600)/4-(%Y-1600)/100+(%Y-1600)/400+1%j-1000-135140)*86400+(1%H-100)*3600+(1%M-100)*60+(1%S-100)") ))
|
||||
}
|
||||
|
||||
# user_homedir returns the home directory for the provided user
|
||||
user_homedir() {
|
||||
local user="$1"
|
||||
|
||||
awk \
|
||||
-v u="$user" \
|
||||
-v FS=':' \
|
||||
'$1==u {print $6}' \
|
||||
/etc/passwd
|
||||
}
|
||||
|
||||
# sponge acts like sponge(1) from moreutils, but is portable.
|
||||
#
|
||||
# It "soaks up" all input from stdin before writing it to the specified output;
|
||||
# helpful for modifying a file in-place with a utility that does not support
|
||||
# it.
|
||||
sponge() {
|
||||
local append=false
|
||||
|
||||
while getopts 'a' opt; do
|
||||
case $opt in
|
||||
a) append=true ;;
|
||||
*) echo "unknown option: $opt" >&2; exit 1;;
|
||||
esac
|
||||
done
|
||||
shift "$(( OPTIND - 1 ))"
|
||||
|
||||
local outfile="$1"
|
||||
local tmpfile
|
||||
|
||||
tmpfile="$(mktemp "$(dirname "$outfile")/tmp-sponge.XXXXXXXX")" &&
|
||||
cat >"$tmpfile" &&
|
||||
if "$append"; then
|
||||
cat "$tmpfile" >>"$outfile"
|
||||
else
|
||||
if [ -f "$outfile" ]; then
|
||||
# NOTE: the stat() call here isn't exactly portable, but both GNU
|
||||
# coreutils and busybox support it, so close enough? Let's
|
||||
# double-check that it returns something sensible just to be sure.
|
||||
local oldperms
|
||||
oldperms="$(stat -c '%a' "$outfile")"
|
||||
|
||||
if [ "${#oldperms}" = "3" ] && [ -z "$(echo "$oldperms" | tr -d '0-9')" ]; then
|
||||
chmod "$oldperms" "$tmpfile"
|
||||
else
|
||||
printf "warning (bad: %s): not setting permssions on: %s\n" "${oldperms}" "$outfile" >&2
|
||||
fi
|
||||
fi
|
||||
if [ -f "$outfile" ]; then
|
||||
mv "$tmpfile" "$outfile"
|
||||
elif [ -n "$outfile" ] && [ ! -e "$outfile" ]; then
|
||||
cat "$tmpfile" >"$outfile"
|
||||
else
|
||||
cat "$tmpfile"
|
||||
fi
|
||||
fi &&
|
||||
rm -f "$tmpfile"
|
||||
}
|
||||
|
|
|
|||
|
|
@ -95,5 +95,48 @@ testEpochseconds() {
|
|||
assertEquals "" "$(epochseconds | tr -d '[0-9]')"
|
||||
}
|
||||
|
||||
testUserHomedir() {
|
||||
assertEquals "$HOME" "$(user_homedir "$USER")"
|
||||
}
|
||||
|
||||
testSponge() {
|
||||
for i in $(seq 1 10000); do
|
||||
echo "i am a test line of length 30" >> "$TEST_TMPDIR/largefile.txt"
|
||||
echo "i am a neat line of length 30" >> "$TEST_TMPDIR/expected.txt"
|
||||
done
|
||||
|
||||
# Modify the file; if we don't sponge, this will probably overwrite things
|
||||
# and won't work.
|
||||
cat "$TEST_TMPDIR/largefile.txt" | \
|
||||
sed 's/test/neat/g' | \
|
||||
sponge "$TEST_TMPDIR/largefile.txt"
|
||||
|
||||
# The files should be equal (currently, we just compare CRCs)
|
||||
assertEquals "$(cksum < "$TEST_TMPDIR/largefile.txt")" "$(cksum < "$TEST_TMPDIR/expected.txt")"
|
||||
}
|
||||
|
||||
testSponge_Permissions() {
|
||||
echo "i am the input file" > "$TEST_TMPDIR/input.txt"
|
||||
echo "i am the output file" > "$TEST_TMPDIR/output.txt"
|
||||
|
||||
# Set a strange permission on the output file that we will replicate.
|
||||
chmod 0741 "$TEST_TMPDIR/output.txt"
|
||||
|
||||
cat "$TEST_TMPDIR/input.txt" | sponge "$TEST_TMPDIR/output.txt"
|
||||
|
||||
# The files should be equal
|
||||
assertEquals "$(cat "$TEST_TMPDIR/input.txt")" "$(cat "$TEST_TMPDIR/output.txt")"
|
||||
assertEquals "741" "$(stat -c '%a' "$TEST_TMPDIR/output.txt")"
|
||||
}
|
||||
|
||||
testSponge_Append() {
|
||||
echo "one" > "$TEST_TMPDIR/input.txt"
|
||||
echo "two" > "$TEST_TMPDIR/output.txt"
|
||||
|
||||
cat "$TEST_TMPDIR/input.txt" | sponge -a "$TEST_TMPDIR/output.txt"
|
||||
|
||||
assertEquals "$(printf 'two\none\n')" "$(cat "$TEST_TMPDIR/output.txt")"
|
||||
}
|
||||
|
||||
# Load shUnit2
|
||||
. ./shunit2
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue