python: Rework filespec install script
authorJeffery To <redacted>
Thu, 29 Jun 2023 07:27:40 +0000 (15:27 +0800)
committerJeffery To <redacted>
Thu, 24 Aug 2023 17:47:43 +0000 (01:47 +0800)
* Support wildcards in install (`+`) paths

* Add fourth parameter to set directory permissions

  If file permissions are given (third parameter), these will now apply
  to files only.

* Add non-recursive set permissions command (`==`)

* Be more strict about filespec format

  Blank lines and lines starting with `#` will be ignored. Other errors
  (unknown command, missing path parameter, etc.) will cause the script
  to exit.

* Be more strict about ensuring paths exist for all commands

* Avoid spawning subshells

This also removes outdated filespec paths in the python3 package; these
paths delete files that are no longer present.

Signed-off-by: Jeffery To <redacted>
lang/python/python-package-install.sh
lang/python/python3/Makefile

index fa42f6f4a80f361a63ff0f68235f284c480d5bed..4e7fb7af5b9cf3982bd9e527bb2a0e84478d225c 100644 (file)
 #!/bin/sh
-set -e
-
-process_filespec() {
-       local src_dir="$1"
-       local dst_dir="$2"
-       local filespec="$3"
-       echo "$filespec" | (
-       IFS='|'
-       while read fop fspec fperm; do
-               local fop=`echo "$fop" | tr -d ' \t\n'`
-               if [ "$fop" = "+" ]; then
-                       if [ ! -e "${src_dir}${fspec}" ]; then
-                               echo "File not found '${src_dir}${fspec}'"
-                               exit 1
-                       fi
-                       dpath=`dirname "$fspec"`
-                       if [ -z "$fperm" ]; then
-                               dperm=`stat -c "%a" ${src_dir}${dpath}`
-                       fi
-                       mkdir -p -m$dperm ${dst_dir}${dpath}
-                       echo "copying: '$fspec'"
-                       cp -fpR ${src_dir}${fspec} ${dst_dir}${dpath}/
-                       if [ -n "$fperm" ]; then
-                               chmod -R $fperm ${dst_dir}${fspec}
-                       fi
-               elif [ "$fop" = "-" ]; then
-                       echo "removing: '$fspec'"
-                       rm -fR ${dst_dir}${fspec}
-               elif [ "$fop" = "=" ]; then
-                       echo "setting permissions: '$fperm' on '$fspec'"
-                       chmod -R $fperm ${dst_dir}${fspec}
-               fi
-       done
-       )
+
+log() {
+       printf '%s\n' "$*"
+}
+
+error() {
+       printf 'Error: %s\n' "$*" >&2
+}
+
+path_exists() {
+       local dir="$1"
+       local path="$2"
+
+       [ -n "$(find "$dir"/$path -print -quit 2>/dev/null)" ]
+}
+
+file_dir_chmod() {
+       local dir="$1"
+       local path="$2"
+       local file_mode="$3"
+       local dir_mode="$4"
+       shift; shift; shift; shift;
+
+       if [ -n "$file_mode" ]; then
+               find "$dir"/$path -type f "$@" -exec chmod "$file_mode" -- '{}' +
+       fi
+
+       if [ -n "$dir_mode" ]; then
+               find "$dir"/$path -type d "$@" -exec chmod "$dir_mode" -- '{}' +
+       fi
 }
 
-src_dir="$1"
-dst_dir="$2"
+src="$1"
+dest="$2"
 filespec="$3"
 
-process_filespec "$src_dir" "$dst_dir" "$filespec" || {
-       echo "process filespec error-ed"
+if [ -z "$src" ]; then
+       error "Missing source directory"
        exit 1
-}
+fi
+if [ -z "$dest" ]; then
+       error "Missing destination directory"
+       exit 1
+fi
+
+while IFS='|' read -r cmd path file_mode dir_mode; do
+
+       # trim whitespace
+
+       cmd="${cmd#"${cmd%%[![:space:]]*}"}"
+       cmd="${cmd%"${cmd##*[![:space:]]}"}"
+
+       path="${path#"${path%%[![:space:]]*}"}"
+       path="${path%"${path##*[![:space:]]}"}"
+
+       file_mode="${file_mode#"${file_mode%%[![:space:]]*}"}"
+       file_mode="${file_mode%"${file_mode##*[![:space:]]}"}"
+
+       dir_mode="${dir_mode#"${dir_mode%%[![:space:]]*}"}"
+       dir_mode="${dir_mode%"${dir_mode##*[![:space:]]}"}"
+
+
+       if [ -z "$cmd" ] || [ "$cmd" != "${cmd#\#}" ]; then
+               continue
+       fi
+
+       if [ -z "$path" ]; then
+               error "Missing path for \"$cmd\""
+               exit 1
+       fi
+
+       case "$cmd" in
+       +)
+               log "Copying: \"$path\""
+
+               if ! path_exists "$src" "$path"; then
+                       error "\"$src/$path\" not found"
+                       exit 1
+               fi
+
+               dir="${path%/*}"
+               mkdir -p "$dest/$dir"
+               cp -fpR "$src"/$path "$dest/$dir/"
+
+               file_dir_chmod "$dest" "$path" "$file_mode" "$dir_mode"
+               ;;
+
+       -)
+               log "Removing: \"$path\""
+
+               if ! path_exists "$dest" "$path"; then
+                       error "\"$dest/$path\" not found"
+                       exit 1
+               fi
+
+               rm -fR -- "$dest"/$path
+               ;;
+
+       =)
+               log "Setting recursive permissions \"${file_mode:-(none)}\"/\"${dir_mode:-(none)}\" on \"$path\""
+
+               if ! path_exists "$dest" "$path"; then
+                       error "\"$dest/$path\" not found"
+                       exit 1
+               fi
+
+               if [ -z "$file_mode$dir_mode" ]; then
+                       error "Missing recursive permissions for \"$path\""
+                       exit 1
+               fi
+
+               file_dir_chmod "$dest" "$path" "$file_mode" "$dir_mode"
+               ;;
+
+       ==)
+               log "Setting permissions \"${file_mode:-(none)}\"/\"${dir_mode:-(none)}\" on \"$path\""
+
+               if ! path_exists "$dest" "$path"; then
+                       error "\"$dest/$path\" not found"
+                       exit 1
+               fi
+
+               if [ -z "$file_mode$dir_mode" ]; then
+                       error "Missing permissions for \"$path\""
+                       exit 1
+               fi
+
+               file_dir_chmod "$dest" "$path" "$file_mode" "$dir_mode" -maxdepth 0
+               ;;
+
+       *)
+               error "Unknown command \"$cmd\""
+               exit 1
+               ;;
+       esac
+
+done << EOF
+$filespec
+EOF
index 45d14379c4e901897ddcb8c3c9821b8cd72e6d74..304e2430418d6540814544195282dd11a8effe31 100644 (file)
@@ -121,13 +121,15 @@ define Py3BasePackage
     PYTHON3_PACKAGES_DEPENDS+=$(1)
   endif
   PYTHON3_LIB_FILES_DEL+=$(2)
-  define Py3Package/$(1)/filespec
-    ifneq ($(2),)
-      $(subst $(space),$(newline),$(foreach lib_file,$(2),+|$(lib_file)))
-      -|/usr/lib/python$(PYTHON3_VERSION)/*/test
-      -|/usr/lib/python$(PYTHON3_VERSION)/*/tests
-    endif
-  endef
+  ifeq ($(2),)
+    Py3Package/$(1)/filespec=
+  else
+    define Py3Package/$(1)/filespec
+      $(foreach lib_file,$(2),
+        +|$(lib_file)
+      )
+    endef
+  endif
   Py3Package/$(1)/install?=:
 endef
 
@@ -240,24 +242,22 @@ PYTHON3_LIB_FILES_DEL+=$(PYTHON3_BASE_LIB_FILES)
 
 define Py3Package/python3-base/filespec
 +|/usr/bin/python$(PYTHON3_VERSION)
-$(subst $(space),$(newline),$(foreach lib_file,$(PYTHON3_BASE_LIB_FILES),+|$(lib_file)))
+$(foreach lib_file,$(PYTHON3_BASE_LIB_FILES),
+  +|$(lib_file)
+)
 endef
 
 define Py3Package/python3-light/filespec
 +|/usr/lib/python$(PYTHON3_VERSION)
 -|/usr/lib/python$(PYTHON3_VERSION)/distutils/cygwinccompiler.py
--|/usr/lib/python$(PYTHON3_VERSION)/distutils/command/wininst*
 -|/usr/lib/python$(PYTHON3_VERSION)/idlelib
 -|/usr/lib/python$(PYTHON3_VERSION)/tkinter
 -|/usr/lib/python$(PYTHON3_VERSION)/turtledemo
--|/usr/lib/python$(PYTHON3_VERSION)/lib-dynload/_test*.so
--|/usr/lib/python$(PYTHON3_VERSION)/pdb.doc
--|/usr/lib/python$(PYTHON3_VERSION)/test
 -|/usr/lib/python$(PYTHON3_VERSION)/webbrowser.py
--|/usr/lib/python$(PYTHON3_VERSION)/*/test
--|/usr/lib/python$(PYTHON3_VERSION)/*/tests
 -|/usr/lib/python$(PYTHON3_VERSION)/_osx_support.py
-$(subst $(space),$(newline),$(foreach lib_file,$(PYTHON3_LIB_FILES_DEL),-|$(lib_file)))
+$(foreach lib_file,$(filter /usr/lib/python$(PYTHON3_VERSION)/%,$(PYTHON3_LIB_FILES_DEL)),
+  -|$(lib_file)
+)
 endef
 
 define Package/libpython3/install
git clone https://git.99rst.org/PROJECT