aboutsummaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
authorEgor Tensin <Egor.Tensin@gmail.com>2021-11-25 19:06:47 +0000
committerEgor Tensin <Egor.Tensin@gmail.com>2021-11-25 19:06:47 +0000
commit4d7904fd36ca5078b47b372691b4c16b256f3307 (patch)
tree5735f76f55dd4853010673a88375b6b136b742c8
parentdebian: 1.0.1-1 (diff)
parentREADME: update (diff)
downloadconfig-links-4d7904fd36ca5078b47b372691b4c16b256f3307.tar.gz
config-links-4d7904fd36ca5078b47b372691b4c16b256f3307.zip
Merge tag 'v1.1' into debian
-rw-r--r--README.md2
-rwxr-xr-xlinks-chmod98
-rwxr-xr-xlinks-remove2
-rwxr-xr-xlinks-update13
-rw-r--r--src/db.sh15
-rwxr-xr-xtest/test.sh79
6 files changed, 203 insertions, 6 deletions
diff --git a/README.md b/README.md
index b2fe286..18d3838 100644
--- a/README.md
+++ b/README.md
@@ -42,7 +42,7 @@ Usage
Symlinks are created & maintained by `links-update`.
```
-usage: links-update [-h|--help] [-d|--database PATH] [-s|--shared-dir DIR] [-n|--dry-run]
+usage: links-update [-h|--help] [-d|--database PATH] [-s|--shared-dir DIR] [-m|--mode MODE] [-n|--dry-run]
```
To remove all symlinks, use `links-remove`.
diff --git a/links-chmod b/links-chmod
new file mode 100755
index 0000000..9c7a427
--- /dev/null
+++ b/links-chmod
@@ -0,0 +1,98 @@
+#!/usr/bin/env bash
+
+# Copyright (c) 2021 Egor Tensin <Egor.Tensin@gmail.com>
+# This file is part of the "Config file sharing" project.
+# For details, see https://github.com/egor-tensin/config-links.
+# Distributed under the MIT License.
+
+# usage: ./links-chmod [-h|--help] [-d|--database PATH] [-s|--shared-dir DIR] [-m|--mode MODE] [-n|--dry-run]
+
+set -o errexit
+set -o nounset
+set -o pipefail
+
+script_name="$( basename -- "${BASH_SOURCE[0]}" )"
+readonly script_name
+script_path="$( realpath --canonicalize-existing -- "${BASH_SOURCE[0]}" )"
+readonly script_path
+script_dir="$( dirname -- "$script_path" )"
+readonly script_dir
+src_dir="$( cd -- "$script_dir/src" && pwd )"
+readonly src_dir
+
+. "$src_dir/common.sh"
+. "$src_dir/os.sh"
+. "$src_dir/path.sh"
+. "$src_dir/vars.sh"
+. "$src_dir/db.sh"
+
+script_usage() {
+ local msg
+ for msg; do
+ echo "$script_name: $msg"
+ done
+
+ echo "usage: $script_name [-h|--help] [-d|--database PATH] [-s|--shared-dir DIR] [-n|--dry-run]
+ -h,--help show this message and exit
+ -d,--database set database file path
+ -s,--shared-dir set top-level shared directory path
+ (current working directory by default)
+ -m,--mode shared files mode (as in chmod)
+ -n,--dry-run don't actually do anything intrusive"
+}
+
+parse_script_options() {
+ while [ "$#" -gt 0 ]; do
+ local key="$1"
+ shift
+
+ case "$key" in
+ -h|--help)
+ script_usage
+ exit 0
+ ;;
+ -n|--dry-run)
+ set_dry_run
+ continue
+ ;;
+ -d|--database|-s|--shared-dir|-m|--mode)
+ ;;
+ *)
+ script_usage "unrecognized parameter: $key" >&2
+ exit 1
+ ;;
+ esac
+
+ if [ "$#" -eq 0 ]; then
+ script_usage "missing argument for parameter: $key" >&2
+ exit 1
+ fi
+
+ local value="$1"
+ shift
+
+ case "$key" in
+ -d|--database)
+ update_database_path "$value"
+ ;;
+ -s|--shared-dir)
+ update_shared_dir "$value"
+ ;;
+ -m|--mode)
+ mode="$value"
+ ;;
+ *)
+ script_usage "unrecognized parameter: $key" >&2
+ exit 1
+ ;;
+ esac
+ done
+}
+
+main() {
+ parse_script_options "$@"
+ read_database
+ chmod_entries "$mode"
+}
+
+main "$@"
diff --git a/links-remove b/links-remove
index 271fa02..ea79596 100755
--- a/links-remove
+++ b/links-remove
@@ -5,7 +5,7 @@
# For details, see https://github.com/egor-tensin/config-links.
# Distributed under the MIT License.
-# usage: ./unlink.sh [-h|--help] [-d|--database PATH] [-s|--shared-dir DIR] [-n|--dry-run]
+# usage: ./links-remove [-h|--help] [-d|--database PATH] [-s|--shared-dir DIR] [-n|--dry-run]
set -o errexit
set -o nounset
diff --git a/links-update b/links-update
index 6c3b633..1e1c829 100755
--- a/links-update
+++ b/links-update
@@ -17,7 +17,7 @@
# `CYGWIN` Windows environment variable value **must** include either
# `winsymlinks:native` or `winsymlinks:nativestrict`!
-# usage: ./update.sh [-h|--help] [-d|--database PATH] [-s|--shared-dir DIR] [-n|--dry-run]
+# usage: ./links-update [-h|--help] [-d|--database PATH] [-s|--shared-dir DIR] [-m|--mode MODE] [-n|--dry-run]
set -o errexit
set -o nounset
@@ -32,6 +32,8 @@ readonly script_dir
src_dir="$( cd -- "$script_dir/src" && pwd )"
readonly src_dir
+mode=''
+
. "$src_dir/common.sh"
. "$src_dir/os.sh"
. "$src_dir/path.sh"
@@ -44,11 +46,12 @@ script_usage() {
echo "$script_name: $msg"
done
- echo "usage: $script_name [-h|--help] [-d|--database PATH] [-s|--shared-dir DIR] [-n|--dry-run]
+ echo "usage: $script_name [-h|--help] [-d|--database PATH] [-s|--shared-dir DIR] [-m|--mode MODE] [-n|--dry-run]
-h,--help show this message and exit
-d,--database set database file path
-s,--shared-dir set top-level shared directory path
(current working directory by default)
+ -m,--mode shared files mode (as in chmod)
-n,--dry-run don't actually do anything intrusive"
}
@@ -66,7 +69,7 @@ parse_script_options() {
set_dry_run
continue
;;
- -d|--database|-s|--shared-dir)
+ -d|--database|-s|--shared-dir|-m|--mode)
;;
*)
script_usage "unrecognized parameter: $key" >&2
@@ -89,6 +92,9 @@ parse_script_options() {
-s|--shared-dir)
update_shared_dir "$value"
;;
+ -m|--mode)
+ mode="$value"
+ ;;
*)
script_usage "unrecognized parameter: $key" >&2
exit 1
@@ -103,6 +109,7 @@ main() {
read_database
unlink_obsolete_entries
link_all_entries
+ test -n "$mode" && chmod_entries "$mode"
write_database
}
diff --git a/src/db.sh b/src/db.sh
index 6145c6d..5eb1697 100644
--- a/src/db.sh
+++ b/src/db.sh
@@ -262,3 +262,18 @@ unlink_obsolete_entries() {
fi
done
}
+
+chmod_entries() {
+ if [ "$#" -ne 1 ]; then
+ echo "usage: ${FUNCNAME[0]} MODE" >&2
+ return 1
+ fi
+
+ local mode="$1"
+ shift
+
+ echo "Applying mode $mode to shared files..."
+ if [ "${#shared_paths[@]}" -ne 0 ]; then
+ is_dry_run || chmod -- "$mode" ${shared_paths[@]+"${shared_paths[@]}"}
+ fi
+}
diff --git a/test/test.sh b/test/test.sh
index 37167ec..de4dd85 100755
--- a/test/test.sh
+++ b/test/test.sh
@@ -58,13 +58,17 @@ call_bin_script() {
}
call_update() {
- call_bin_script "$script_dir/../links-update"
+ call_bin_script "$script_dir/../links-update" "$@"
}
call_unlink() {
call_bin_script "$script_dir/../links-remove"
}
+call_chmod() {
+ call_bin_script "$script_dir/../links-chmod" "$@"
+}
+
verify_output() {
if [ "$#" -lt 1 ] || [ "$#" -gt 2 ]; then
echo "usage: ${FUNCNAME[0]} EXPECTED_OUTPUT [DEST_DIR]" >&2
@@ -79,6 +83,7 @@ verify_output() {
local dest_dir="$test_dest_dir"
[ "$#" -ge 2 ] && dest_dir="$2"
+ local actual_output
actual_output="$( find "$dest_dir" -printf '%h/%f->%l\n' | sort )"
echo
echo 'Actual directory structure:'
@@ -93,6 +98,33 @@ verify_output() {
fi
}
+verify_mode() {
+ if [ "$#" -ne 2 ]; then
+ echo "usage: ${FUNCNAME[0]} EXPECTED_MODE FILE" >&2
+ return 1
+ fi
+
+ local expected_mode="$1"
+ local path="$2"
+
+ echo
+ echo "Checking permissions for file: $path"
+ echo "Expected mode: $expected_mode"
+
+ local actual_mode
+ actual_mode="$( stat -c '%a' -- "$path" )"
+ actual_mode="0$actual_mode"
+
+ echo "Actual mode: $actual_mode"
+
+ if [ "$actual_mode" = "$expected_mode" ]; then
+ echo "... They match!"
+ else
+ echo "... They don't match."
+ return 1
+ fi
+}
+
test_update_works() {
# Basic test to make sure update.sh actually creates the proper symlinks.
@@ -308,6 +340,48 @@ test_symlink_unlink_works() {
test "$copy_content" = '3'
}
+test_chmod_works() {
+ # Test that links-chmod works.
+ new_test
+ call_update
+
+ local expected_output="$test_dest_dir->
+$test_dest_dir/1.txt->$test_src_dir/%DEST%/1.txt
+$test_dest_dir/bar->
+$test_dest_dir/bar/3.txt->$test_src_dir/%DEST%/bar/3.txt
+$test_dest_dir/bar/baz->
+$test_dest_dir/bar/baz/4.txt->$test_src_dir/%DEST%/bar/baz/4.txt
+$test_dest_dir/foo->
+$test_dest_dir/foo/2.txt->$test_src_dir/%DEST%/foo/2.txt"
+ verify_output "$expected_output"
+
+ echo
+ echo 'Verifying 1.txt (the shared file) permissions...'
+
+ verify_mode 0644 "$test_src_dir/%DEST%/1.txt"
+ call_chmod --mode 0600
+ verify_mode 0600 "$test_src_dir/%DEST%/1.txt"
+}
+
+test_update_chmod() {
+ # Test that links-update --mode works.
+ new_test
+ local expected_mode='0622'
+ call_update --mode "$expected_mode"
+
+ local expected_output="$test_dest_dir->
+$test_dest_dir/1.txt->$test_src_dir/%DEST%/1.txt
+$test_dest_dir/bar->
+$test_dest_dir/bar/3.txt->$test_src_dir/%DEST%/bar/3.txt
+$test_dest_dir/bar/baz->
+$test_dest_dir/bar/baz/4.txt->$test_src_dir/%DEST%/bar/baz/4.txt
+$test_dest_dir/foo->
+$test_dest_dir/foo/2.txt->$test_src_dir/%DEST%/foo/2.txt"
+ verify_output "$expected_output"
+
+ verify_mode "$expected_mode" "$test_src_dir/%DEST%/1.txt"
+}
+
main() {
test_update_works
test_unlink_works
@@ -320,6 +394,9 @@ main() {
test_symlink_update_works
test_symlink_unlink_works
+
+ test_chmod_works
+ test_update_chmod
}
main