diff --git a/.config.example b/.config.example
index ae8b803..bba4fda 100644
--- a/.config.example
+++ b/.config.example
@@ -2,4 +2,4 @@ SSH_ADDR=example.com
SSH_USER=zpkg
HTTP_ADDR=example.com
HTTP_PATH=zpkg
-PKG_PATH='$HOME/pkg'
+PKG_PATH=pkg
diff --git a/README.md b/README.md
index 81481a7..4ebd53f 100644
--- a/README.md
+++ b/README.md
@@ -23,7 +23,7 @@ Optional:
wget http://zpkg.zawz.net/install.sh
sh install.sh
```
-> By default the config is installed to /etc/zpkg.
+> By default the config is installed to /etc/zpkg
> This can be changed with the -c option
If you wish to use another repository, substitute `zpkg.zawz.net` for your desired target
@@ -37,7 +37,7 @@ sudo rm -rd /etc/zpkg
### Using
-See `zpkg -h`
+See `zpkg -h` for details
## Deploy on a server
@@ -49,7 +49,7 @@ To deploy on a server you need:
- HTTP server
- dedicated zpkg user
-You need to be able to SSH to the zpkg user. SSH keys are recommended
+You need to be able to SSH to the zpkg user, SSH keys are recommended
### Process
@@ -64,20 +64,22 @@ You need to be able to SSH to the zpkg user. SSH keys are recommended
```
.
+-- DEPS
++-- DESC
+-- ROOT
| +-- /
+-- HOME
+-- ~
```
-- The ROOT directory repsesents the root filesystem
+- The ROOT directory represents the root filesystem
- The HOME directory represents the home directory of the user
- The DEPS file contains dependency packages separated by spaces or newlines. Dependencies are package names from the repository
+- The DESC file contains the description of the package
### Deploying packages
`zpkg deploy
`
> Target directories are structured as described above
-> The package name is the name of the directory
+> The name of the directory is the package name
## Functionality
@@ -90,4 +92,4 @@ You need to be able to SSH to the zpkg user. SSH keys are recommended
- Versions
- Multi-repo
-
+- Hooks
diff --git a/compile.sh b/compile.sh
index 15b5765..bff27fd 100755
--- a/compile.sh
+++ b/compile.sh
@@ -3,7 +3,7 @@
# config
# no spaces in srcdir or ordered files
SRCDIR=src
-ordered='options.sh config.sh main.sh'
+ordered='env.sh options.sh config.sh main.sh'
# process
COMMENTSCRIPT="/^\s*#/d;s/\s*#[^\"']*$//"
diff --git a/completion/zpkg.bash b/completion/zpkg.bash
index a6c2e0b..210fc42 100644
--- a/completion/zpkg.bash
+++ b/completion/zpkg.bash
@@ -7,7 +7,7 @@ _zpkg_completion()
_cw1_file="deploy"
if [ "$COMP_CWORD" = "1" ] ; then
_compwords=$_cw1
- elif [ "$COMP_CWORD" -gt "1" ] && [ -n "$(echo "$_cw1_pkgw" | grep -w "${COMP_WORDS[1]}" 2>/dev/null)" ] ; then
+ elif [ "$COMP_CWORD" -gt "1" ] && echo "$_cw1_pkgw" | grep -qw -- "${COMP_WORDS[1]}" ; then
_compwords=$(zpkg list-all 2>/dev/null)
fi
COMPREPLY=($(compgen -W "$_compwords" "${COMP_WORDS[$COMP_CWORD]}" 2>/dev/null))
diff --git a/src/config.sh b/src/config.sh
index 6112ded..16fb520 100644
--- a/src/config.sh
+++ b/src/config.sh
@@ -21,7 +21,7 @@ then
fi
if [ ! -f "$config_file" ]
then
- echo "Error: no config file '$config_file'" > /dev/stderr
+ echo "Error: no config file '$config_file'" >&2
exit 1
fi
diff --git a/src/deploy.sh b/src/deploy.sh
index 9cafa25..0dbb914 100644
--- a/src/deploy.sh
+++ b/src/deploy.sh
@@ -6,28 +6,27 @@ package()
src="$1"
pkg="$2"
echo "Packaging $(getname "$src"): $(du -sh "$src" | awk '{print $1}')iB"
+
+ tmpdir="/tmp/zpkg_$(random_string 5)"
+ mkdir -p "$tmpdir"
if [ ! -d "$src/ROOT" ] && [ ! -d "$src/HOME" ] && [ ! -f "$src/DEPS" ]
then
- tmpdir="/tmp/zpkg$(random_string 5)"
- mkdir -p "$tmpdir"
- cp -r "$src" "$tmpdir/ROOT"
- src="$tmpdir"
- clean_needed=true
+ mkdir -p "$tmpdir/package"
+ cp -r "$src" "$tmpdir/package/ROOT"
+ else
+ cp -r "$src" "$tmpdir/package"
fi
(
- cd "$src"
+ cd "$tmpdir/package"
if which pv >/dev/null 2>&1
then
- tar -cf - --owner=0 --group=0 -P * | pv -s "$(du -sb . | awk '{print $1}')" | xz > "$pkg"
+ tar -cf - --owner=0 --group=0 -P * | pv -s "$(du -sb . | awk '{print $1}')" | xz > "../$pkg"
else
- tar -cvJf - --owner=0 --group=0 * > "$pkg"
+ tar -cvJf - --owner=0 --group=0 * > "../$pkg"
fi
)
- mv "$src/$pkg" ./
- if [ -n "$clean_needed" ]
- then
- rm -rd "$tmpdir"
- fi
+ mv "$tmpdir/$pkg" ./
+ rm -rd "$tmpdir"
}
deploy_package()
diff --git a/src/fetch.sh b/src/fetch.sh
index d4c2930..bd0998b 100644
--- a/src/fetch.sh
+++ b/src/fetch.sh
@@ -1,9 +1,11 @@
#!/bin/sh
+# $1 = package name , $2 = output
fetch_package()
{
- wget "$HTTP_ADDRESS/$1.tar.xz" -q --show-progress -O "$1.tar.xz" 2>&1
- return $?
+ out="$2"
+ [ -z "$out" ] && out="$1.tar.xz"
+ wget "$HTTP_ADDRESS/$1.tar.xz" -q --show-progress -O "$out" 2>&1
}
# $1 = prefix
@@ -13,7 +15,7 @@ fetch_pkglist()
$1 mv pkglist pkglist_bak 2>/dev/null
if ! $1 wget "$HTTP_ADDRESS/pkglist" -q --show-progress -O pkglist 2>&1
then
- echo "Couldn't fetch server data" > /dev/stderr
+ echo "Couldn't fetch server data" >&2
$1 mv pkglist_bak pkglist 2>/dev/null
return 1
else
diff --git a/src/install.sh b/src/install.sh
index 32e4660..d349518 100644
--- a/src/install.sh
+++ b/src/install.sh
@@ -39,20 +39,22 @@ move_files()
install_package()
{
- tmpdir="/tmp/zpkg$(random_string 5)"
+ tmpdir="/tmp/zpkg_$(random_string 5)"
mkdir -p "$tmpdir"
(
cd "$tmpdir"
if ! fetch_package "$1"
then
- echo "Package '$1' not found" > /dev/stderr
+ echo "Package '$1' not found" >&2
return 1
fi
- unpack "$1.tar.xz"
- sudo mv "$1.tar.xz" "$PKG_PATH"
+ sudo cp "$1.tar.xz" "$PKG_PATH"
+ unpack "$1.tar.xz" || return $?
move_files ROOT / sudo 2>/dev/null
move_files HOME "$HOME" 2>/dev/null
add_package_entry "$1"
- ) || return $?
+ )
+ ret=$?
rm -rd "$tmpdir" 2>/dev/null
+ return $ret
}
diff --git a/src/main.sh b/src/main.sh
index 730e100..686f25f 100644
--- a/src/main.sh
+++ b/src/main.sh
@@ -5,160 +5,135 @@ if [ -z "$opt_f" ] ; then
fi
-if [ -n "$1" ]
-then
-
- if [ "$1" = "list" ]
+case "$1" in
+list) awk '{print $1}' "$PKG_PATH/installed" 2>/dev/null ;;
+list-all) awk '{print $1}' "$PKG_PATH/pkglist" 2>/dev/null ;;
+update-database) fetch_pkglist sudo ;;
+fetch)
+ if [ -z "$2" ]
then
- awk '{print $1}' "$PKG_PATH/installed" 2>/dev/null
-
- elif [ "$1" = "list-all" ]
- then
- awk '{print $1}' "$PKG_PATH/pkglist" 2>/dev/null
-
-
- elif [ "$1" = "fetch" ]
- then
-
- if [ -z "$2" ]
- then
- echo "No package specified" > /dev/stderr
- else
- shift 1
- for I in $*
- do
- fetch_package "$I"
- done
- fi
-
-
- elif [ "$1" = "show" ]
- then
-
- if [ -z "$2" ]
- then
- echo "No package specified" > /dev/stderr
- else
- shift 1
- for I in $*
- do
- if is_installed "$I"
- then
- view_package "$I"
- else
- echo "No package '$I' installed" > /dev/stderr
- fi
- done
- fi
-
- elif [ "$1" = "deps" ]
- then
-
- if [ -z "$2" ]
- then
- echo "No package specified" > /dev/stderr
- else
- shift 1
- resolve_deps $*
- fi
-
- elif [ "$1" = "install" ]
- then
-
- fetch_pkglist sudo || exit $?
- if [ -z "$2" ]
- then
- echo "No package specified" > /dev/stderr
- else
- shift 1
- pkglist=$(LOG=true resolve_packages $*) || exit $?
- pkglist=$(INCLUDE_PACKAGES=true resolve_deps $* | tr '\n' ' ')
- echo "Installing packages: $pkglist"
- for I in $pkglist
- do
- if is_installed "$I"
- then
- remove_package "$I"
- fi
- install_package "$I"
- done
- fi
-
- elif [ "$1" = "remove" ]
- then
-
- if [ -z "$2" ]
- then
- echo "No package specified" > /dev/stderr
- else
- shift 1
- for I in $*
- do
- remove_package "$I"
- done
- fi
-
- elif [ "$1" = "update-database" ]
- then
-
- fetch_pkglist sudo
-
- elif [ "$1" = "update" ]
- then
-
- fetch_pkglist sudo || exit 1
- r_pkg=$(removed_packages)
- o_pkg=$(outdated_packages)
- if [ -n "$r_pkg" ]
- then
- echo "Removing packages: "$r_pkg
- for I in $r_pkg
- do
- remove_package $I
- done
- fi
- if [ -n "$o_pkg" ]
- then
- echo "Updating packages: "$o_pkg
- for I in $o_pkg
- do
- remove_package $I
- install_package $I
- done
- fi
-
- elif [ "$1" = "list-outdated" ]
- then
-
- tmpdir="/tmp/zpkg$(random_string 5)"
- virtual_config_path "$tmpdir" || exit $?
- fetch_pkglist sudo > /dev/null || exit $?
- outdated_packages
- sudo rm -rd "$tmpdir"
-
- elif [ "$1" = "list-removed" ]
- then
-
- tmpdir="/tmp/zpkg$(random_string 5)"
- virtual_config_path "$tmpdir" || exit $?
- fetch_pkglist sudo > /dev/null || exit $?
- removed_packages
- sudo rm -rd "$tmpdir"
-
- elif [ "$1" = "deploy" ]
- then
-
+ echo "No package specified" >&2
+ else
shift 1
for I in $*
do
- deploy_folder "$I" || exit 1
+ fetch_package "$I"
done
- update_remote_database
-
- else
- usage
fi
-
-else
- usage
-fi
+ ;;
+show)
+ if [ -z "$2" ]
+ then
+ echo "No package specified" >&2
+ else
+ shift 1
+ for I in $*
+ do
+ if is_installed "$I"
+ then
+ view_package "$I"
+ else
+ wget "$HTTP_ADDRESS/$1.tar.xz" -q -O - 2>/dev/null | view_package_file - || { echo "Could not fetch package '$I'" >&2 ; return 1 ; }
+ fi
+ done
+ fi
+ ;;
+deps)
+ if [ -z "$2" ]
+ then
+ echo "No package specified" >&2
+ else
+ shift 1
+ resolve_deps $* || exit $?
+ fi
+ ;;
+show)
+ if [ -z "$2" ]
+ then
+ echo "No package specified" >&2
+ else
+ shift 1
+ for N
+ do
+ package_info $N || exit $?
+ done
+ fi
+ ;;
+install)
+ fetch_pkglist sudo || exit $?
+ if [ -z "$2" ]
+ then
+ echo "No package specified" >&2
+ else
+ shift 1
+ pkglist=$(LOG=true resolve_packages $*) || exit $?
+ pkglist=$(INCLUDE_PACKAGES=true resolve_deps $* | tr '\n' ' ')
+ echo "Installing packages: $pkglist"
+ for I in $pkglist
+ do
+ if is_installed "$I"
+ then
+ remove_package "$I"
+ fi
+ install_package "$I"
+ done
+ fi
+ ;;
+remove)
+ if [ -z "$2" ]
+ then
+ echo "No package specified" >&2
+ else
+ shift 1
+ for I in $*
+ do
+ remove_package "$I"
+ done
+ fi
+ ;;
+update)
+ fetch_pkglist sudo || exit 1
+ r_pkg=$(removed_packages)
+ o_pkg=$(outdated_packages)
+ if [ -n "$r_pkg" ]
+ then
+ echo "Removing packages: "$r_pkg
+ for I in $r_pkg
+ do
+ remove_package $I
+ done
+ fi
+ if [ -n "$o_pkg" ]
+ then
+ echo "Updating packages: "$o_pkg
+ for I in $o_pkg
+ do
+ remove_package $I
+ install_package $I
+ done
+ fi
+ ;;
+list-outdated)
+ tmpdir="/tmp/zpkg_$(random_string 5)"
+ virtual_config_path "$tmpdir" || exit $?
+ fetch_pkglist > /dev/null || exit $?
+ outdated_packages
+ rm -rd "$tmpdir"
+ ;;
+list-removed)
+ tmpdir="/tmp/zpkg_$(random_string 5)"
+ virtual_config_path "$tmpdir" || exit $?
+ fetch_pkglist > /dev/null || exit $?
+ removed_packages
+ rm -rd "$tmpdir"
+ ;;
+deploy)
+ shift 1
+ for I in $*
+ do
+ deploy_folder "$I" || exit 1
+ done
+ update_remote_database
+ ;;
+*) usage && exit 1 ;;
+esac
diff --git a/src/print.sh b/src/print.sh
index 1854387..779039a 100644
--- a/src/print.sh
+++ b/src/print.sh
@@ -2,8 +2,8 @@
usage()
{
- echo "$fname [options] "
- echo '
+ echo "$fname [options]
+
Operations:
update Update packages
update-database Update only database
@@ -11,6 +11,7 @@ Operations:
remove Remove packages
fetch Fetch packages into current directory
show Show package files
+ deps Show dependencies of package
list List currently installed packages
list-all List all packages in repository
list-outdated List outdated packages
@@ -21,10 +22,43 @@ Admin operations:
Options:
-h Display this help
-c Custom config path
- -f Force running even when root
-'
+ -f Force running when root
+"
}
error() {
printf "\033[1;31m%s\033[0m\n" "$1" >&2
}
+
+# $1 = package name
+package_info() {
+ unset cleanup
+ status="not installed"
+ grep -wq "^$1" "$PKG_PATH/pkglist" 2>/dev/null || { echo "Package '$I' not found" && return 1; }
+ grep -wq "^$1" "$PKG_PATH/installed" 2>/dev/null && status=installed
+ if [ "$status" = "installed" ] && [ -f "$PKG_PATH/$1.tar.xz" ]
+ then
+ pkg="$PKG_PATH/$1.tar.xz"
+ else
+ tmpdir="/tmp/zpkg_$(random_string 5)"
+ pwd=$(pwd)
+ mkdir "$tmpdir"
+ fetch_package "$1" >/dev/null 2>&1 || { echo "Error fetching package" >&2 && ret=$?; }
+ pkg="$1.tar.xz"
+ fi
+ deps=$(deps "$1")
+ desc=$(desc "$pkg" 2>/dev/null)
+ csize=$(stat -c '%s' "$pkg" | numfmt --to=iec-i --suffix=B --padding 6)
+ isize=$(xz -dc "$pkg" | wc -c | numfmt --to=iec-i --suffix=B --padding 6)
+ [ -n "$cleanup" ] && { cd "$pwd"; rm -rd "$tmpdir"; }
+
+ [ -n "$ret" ] && return $ret
+
+ printf "Name: %s\n" "$1"
+ printf "Description: %s\n" "$desc"
+ echo ""
+ printf "Status: %s\n" "$status"
+ printf "Dependencies: %s\n" "$(deps "$1" | tr -s ' \n' ' ')"
+ printf "Package size: %s\n" "$csize"
+ printf "Installed size: %s\n" "$isize"
+}
diff --git a/src/remove.sh b/src/remove.sh
index dd7a874..3946c01 100644
--- a/src/remove.sh
+++ b/src/remove.sh
@@ -19,7 +19,7 @@ remove_package()
archive="$(pwd)/$1.tar.xz"
if [ ! -f "$archive" ] || ! grep -q -w "^$1" installed
then
- echo "Package '$1' not installed" > /dev/stderr
+ echo "Package '$1' not installed" >&2
return 1
fi
echo "Removing $1"
diff --git a/src/util.sh b/src/util.sh
index 8cc12f9..7e6f0c9 100644
--- a/src/util.sh
+++ b/src/util.sh
@@ -28,7 +28,7 @@ root_check()
{
if [ "$(id | cut -d'=' -f2 | cut -d'(' -f1)" -eq 0 ]
then
- echo "Cannot run as root" > /dev/stderr
+ echo "Cannot run as root" >&2
return 1
fi
return 0
diff --git a/src/view.sh b/src/view.sh
index c976492..da341ae 100644
--- a/src/view.sh
+++ b/src/view.sh
@@ -3,7 +3,13 @@
deps()
{
cd "$PKG_PATH"
- grep -w "^$1" pkglist | cut -d' ' -f3-
+ l=$(grep -w "^$1" pkglist) || return $?
+ echo "$l" | cut -d' ' -f3-
+}
+
+# $1 = pkg file
+desc() {
+ tar -xOf "$1" DESC
}
resolve_packages()
@@ -14,7 +20,7 @@ resolve_packages()
do
if ! grep -wq "^$I" pkglist 2>/dev/null
then
- [ "$LOG" = "true" ] && echo "Package '$I' not found" > /dev/stderr
+ [ "$LOG" = "true" ] && echo "Package '$I' not found" >&2
RET=1
else
echo "$I"
@@ -27,12 +33,14 @@ resolve_packages()
resolve_deps()
{
ALLDEPS=""
+ RET=0
for I in $*
do
- ALLDEPS="$ALLDEPS $(deps $I)"
+ ALLDEPS="$ALLDEPS $(deps $I)" || { echo "Package '$I' not found" >&2 ; RET=$((RET+1)) ; }
done
[ "$INCLUDE_PACKAGES" = "true" ] && ALLDEPS="$ALLDEPS $*"
echo "$ALLDEPS" | tr -s ' \n' '\n' | sort | uniq | sed '/^$/d'
+ return $RET
}
is_installed()
@@ -42,10 +50,15 @@ is_installed()
return $?
}
-view_package()
-{
- cd "$PKG_PATH"
- tar -tf "$1.tar.xz" | sed "s|^ROOT/|/|g ; /\/$/d ; s|^HOME/|$HOME/|g ; /^DEPS/d"
+# $1 = file
+view_package_file() {
+ tree=$(tar -tJf "$1" 2>/dev/null) || exit $?
+ echo "$tree" | sed "s|^ROOT/|/|g ; /\/$/d ; s|^HOME/|$HOME/|g ; /^DEPS/d" 2>/dev/null
+}
+
+# $1 = package name
+view_package() {
+ cd "$PKG_PATH" && view_package_file "$1.tar.xz"
}
removed_packages()