From c492c53a9867e1218c5a5aba6ac987257e128495 Mon Sep 17 00:00:00 2001
From: Takashi Yoshi <takashi@yoshi.email>
Date: Fri, 7 Dec 2018 16:56:36 +0100
Subject: [PATCH 1/4] [type/__package_pkg_openbsd] Send error messages to
 stderr

---
 cdist/conf/type/__package_pkg_openbsd/gencode-remote | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/cdist/conf/type/__package_pkg_openbsd/gencode-remote b/cdist/conf/type/__package_pkg_openbsd/gencode-remote
index 61383edb..a189eeac 100755
--- a/cdist/conf/type/__package_pkg_openbsd/gencode-remote
+++ b/cdist/conf/type/__package_pkg_openbsd/gencode-remote
@@ -96,7 +96,7 @@ if [ \$? -ne 0 ]; then
     if [ -z "\${status}" ]; then
       status="Failed to add package, uncaught exception."
     fi
-    echo "Error: \$status"
+    echo "Error: \$status" >&2
     exit 1
 fi
 eof
@@ -114,7 +114,7 @@ if [ \$? -eq 0 ]; then
     if [ -z "\${status}" ]; then
       status="Failed to remove package, uncaught exception."
     fi
-    echo "Error: \$status"
+    echo "Error: \$status" >&2
     exit 1
 fi
 eof

From 827081f8a280742ff7309515f476002717c18c1b Mon Sep 17 00:00:00 2001
From: Takashi Yoshi <takashi@yoshi.email>
Date: Fri, 7 Dec 2018 17:32:43 +0100
Subject: [PATCH 2/4] [type/__package_pkg_openbsd/explorer/pkg_version] Fix
 version extraction

The earlier code stripped away all non-numeric parts of the version number.

E.g. "5.6.38p0" would be trimmed to "5.6.38"
---
 .../type/__package_pkg_openbsd/explorer/pkg_version   | 11 ++++++++---
 1 file changed, 8 insertions(+), 3 deletions(-)

diff --git a/cdist/conf/type/__package_pkg_openbsd/explorer/pkg_version b/cdist/conf/type/__package_pkg_openbsd/explorer/pkg_version
index 212f0d96..71fccb42 100755
--- a/cdist/conf/type/__package_pkg_openbsd/explorer/pkg_version
+++ b/cdist/conf/type/__package_pkg_openbsd/explorer/pkg_version
@@ -19,7 +19,7 @@
 # along with cdist. If not, see <http://www.gnu.org/licenses/>.
 #
 #
-# Retrieve the status of a package - parsed dpkg output
+# Retrieve the status of a package - parsed pkg_info output
 #
 
 if [ -f "$__object/parameter/name" ]; then
@@ -28,5 +28,10 @@ else
    name="$__object_id"
 fi
 
-#TODO: Is there a better way?
-pkg_info | grep "^$name-[0-9]" | sed 's|.*\(-[0-9][0-9.]*\).*|\1|' | sed 's/-//'
+# Extract version number from pkg_info.
+# Refer to packages-specs(7) for more information regarding the format.
+
+# ATTENTION: If $name is just a stem (e.g. "php" or "python"), there may be
+#            multiple results. pkg_info prints a line for each version.
+
+pkg_info -q -I "inst:$name" | sed -e 's/^\([^-]*-\)*\([0-9][^-]*\).*$/\2/'

From 498628d16a769132fe68c95f259c3bb557aab7e9 Mon Sep 17 00:00:00 2001
From: Takashi Yoshi <takashi@yoshi.email>
Date: Fri, 7 Dec 2018 19:02:43 +0100
Subject: [PATCH 3/4] [type/__package_pkg_openbsd] Misc. fixes and improvements

---
 .../__package_pkg_openbsd/explorer/pkg_state  | 49 +++++++++++++++++++
 .../explorer/pkg_version                      |  3 +-
 .../type/__package_pkg_openbsd/gencode-remote | 12 ++---
 3 files changed, 55 insertions(+), 9 deletions(-)
 create mode 100755 cdist/conf/type/__package_pkg_openbsd/explorer/pkg_state

diff --git a/cdist/conf/type/__package_pkg_openbsd/explorer/pkg_state b/cdist/conf/type/__package_pkg_openbsd/explorer/pkg_state
new file mode 100755
index 00000000..9cd17787
--- /dev/null
+++ b/cdist/conf/type/__package_pkg_openbsd/explorer/pkg_state
@@ -0,0 +1,49 @@
+#!/bin/sh
+#
+# Copyright 2018, Takashi Yoshi <takashi@yoshi.email>
+#
+# This file is part of cdist.
+#
+# cdist is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# cdist is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with cdist. If not, see <http://www.gnu.org/licenses/>.
+#
+#
+# Retrieve the status of a package - parsed pkg_info output
+#
+
+if [ -f "${__object}/parameter/name" ]
+then
+	pkgid="$(cat "${__object}/parameter/name")"
+else
+	pkgid="${__object_id}"
+fi
+
+if [ -f "${__object}/parameter/version" ]
+then
+	pkgid="${pkgid}-$(cat "${__object}/parameter/version")"
+fi
+
+if [ -f "${__object}/parameter/flavor" ]
+then
+	# If a flavor but no version is given we need to add another -,
+	# otherwise pkg_info confuses the flavor with the version.
+	[ -f "${__object}/parameter/version" ] || pkgid="${pkgid}-"
+
+	pkgid="${pkgid}-$(cat "${__object}/parameter/flavor")"
+fi
+
+
+pkg_info -q -I "inst:${pkgid}" >/dev/null 2>&1 \
+	&& echo 'present' || echo 'absent'
+
+exit 0
diff --git a/cdist/conf/type/__package_pkg_openbsd/explorer/pkg_version b/cdist/conf/type/__package_pkg_openbsd/explorer/pkg_version
index 71fccb42..9b51a588 100755
--- a/cdist/conf/type/__package_pkg_openbsd/explorer/pkg_version
+++ b/cdist/conf/type/__package_pkg_openbsd/explorer/pkg_version
@@ -2,6 +2,7 @@
 #
 # 2011 Andi Brönnimann (andi-cdist at v-net.ch)
 # Copyright 2017, Philippe Gregoire <pg@pgregoire.xyz>
+# Copyright 2018, Takashi Yoshi <takashi@yoshi.email>
 #
 # This file is part of cdist.
 #
@@ -19,7 +20,7 @@
 # along with cdist. If not, see <http://www.gnu.org/licenses/>.
 #
 #
-# Retrieve the status of a package - parsed pkg_info output
+# Retrieve the version of a package - parsed pkg_info output
 #
 
 if [ -f "$__object/parameter/name" ]; then
diff --git a/cdist/conf/type/__package_pkg_openbsd/gencode-remote b/cdist/conf/type/__package_pkg_openbsd/gencode-remote
index a189eeac..0a79fca3 100755
--- a/cdist/conf/type/__package_pkg_openbsd/gencode-remote
+++ b/cdist/conf/type/__package_pkg_openbsd/gencode-remote
@@ -2,6 +2,7 @@
 #
 # 2011 Andi Brönnimann (andi-cdist at v-net.ch)
 # 2012 Nico Schottelius (nico-cdist at schottelius.org)
+# 2018 Takashi Yoshi <takashi@yoshi.email>
 #
 # This file is part of cdist.
 #
@@ -72,12 +73,7 @@ else
   fi
 fi                                                                              
 
-if [ "$pkg_version" ]; then
-    state_is="present"
-else
-    state_is="absent"
-fi
-
+state_is="$(cat "$__object/explorer/pkg_state")"
 [ "$state_is" = "$state_should" ] && exit 0
 
 case "$state_should" in
@@ -88,7 +84,7 @@ if [ X != X"${pkg_path}" ]; then
     PKG_PATH="${pkg_path}"; export PKG_PATH
 fi
 status=\$(pkg_add "$pkgopts" "$pkgid" 2>&1)
-pkg_info | grep "^${name}.*${version}.*${flavor}" > /dev/null 2>&1
+pkg_info -q -I "inst:$pkgid" | grep -q "^${name}-${version}.*${flavor}$" 2>/dev/null
 
 # We didn't find the package in the list of 'installed packages', so it failed
 # This is necessary because pkg_add doesn't return properly
@@ -106,7 +102,7 @@ eof
         # use this because pkg_add doesn't properly handle errors
         cat << eof
 status=\$(pkg_delete "$pkgopts" "$pkgid")
-pkg_info | grep "^${name}.*${version}.*${flavor}" > /dev/null 2>&1
+pkg_info -q -I "inst:$pkgid" | grep -q "^${name}-${version}.*${flavor}" 2>/dev/null
 
 # We found the package in the list of 'installed packages'
 # This would indicate that pkg_delete failed, send the output of pkg_delete

From aa456ab6c18754fda8b1cb6c07efb9511acbe236 Mon Sep 17 00:00:00 2001
From: Takashi Yoshi <takashi@yoshi.email>
Date: Fri, 14 Dec 2018 12:35:04 +0100
Subject: [PATCH 4/4] [type/__package_pkg_openbsd] Clean up code

---
 .../type/__package_pkg_openbsd/gencode-remote | 150 +++++++++---------
 1 file changed, 74 insertions(+), 76 deletions(-)

diff --git a/cdist/conf/type/__package_pkg_openbsd/gencode-remote b/cdist/conf/type/__package_pkg_openbsd/gencode-remote
index 0a79fca3..97f9ca46 100755
--- a/cdist/conf/type/__package_pkg_openbsd/gencode-remote
+++ b/cdist/conf/type/__package_pkg_openbsd/gencode-remote
@@ -23,100 +23,98 @@
 # Manage packages with pkg on OpenBSD
 #
 
-# Debug
-# exec >&2
-# set -x
+os_version=$(cat "${__global}/explorer/os_version")
+machine=$(cat "${__global}/explorer/machine")
 
-os_version="$(cat "$__global/explorer/os_version")"
-machine="$(cat "$__global/explorer/machine")"
-
-if [ -f "$__object/parameter/version" ]; then
-	version="$(cat "$__object/parameter/version")"
+if [ -f "${__object}/parameter/version" ]; then
+	version=$(cat "${__object}/parameter/version")
 fi
 
-if [ -f "$__object/parameter/flavor" ]; then
-	flavor="$(cat "$__object/parameter/flavor")"
+if [ -f "${__object}/parameter/flavor" ]; then
+	flavor=$(cat "${__object}/parameter/flavor")
 fi
 
-# do not show progress bar
-pkgopts="-x"
+# Do not show progress bar
+pkgopts='-x'
 
-if [ -f "$__object/parameter/name" ]; then
-   name=$(cat "$__object/parameter/name")
+name="${__object_id}"
+if [ -f "${__object}/parameter/name" ]; then
+	name=$(cat "${__object}/parameter/name")
+fi
+
+if [ -n "${version}" ] && [ -n "${flavor}" ]; then
+	pkgid="${name}-${version}-${flavor}"
+elif [ -n "${version}" ]; then
+	pkgid="${name}-${version}"
+elif [ -f "${__object}/parameter/flavor" ]; then
+	pkgid="${name}--${flavor}"
 else
-   name="$__object_id"
+	pkgid="${name}"
 fi
 
-if [ -n "$version" ] && [ -n "$flavor" ]; then
-   pkgid="$name-$version-$flavor"
-elif [ -n "$version" ]; then
-   pkgid="$name-$version"
-elif [ -n "$flavor" ]; then
-   pkgid="$name--$flavor"
-elif [ -f "$__object/parameter/flavor" ]; then
-   pkgid="$name--"
+state_should=$(cat "${__object}/parameter/state")
+
+pkg_version=$(cat "${__object}/explorer/pkg_version")
+
+if [ -f "${__object}/parameter/pkg_path" ]; then
+	pkg_path=$(cat "${__object}/parameter/pkg_path")
 else
-   pkgid="$name"
+	has_installurl=$(cat "${__object}/explorer/has_installurl")
+	if [ 'yes' != "${has_installurl}" ]; then
+		# There is no default PKG_PATH, try to provide one
+		pkg_path="ftp://ftp.openbsd.org/pub/OpenBSD/${os_version}/packages/${machine}/"
+	fi
 fi
 
-state_should="$(cat "$__object/parameter/state")"
+state_is=$(cat "${__object}/explorer/pkg_state")
+[ "${state_is}" = "${state_should}" ] && exit 0
 
-pkg_version="$(cat "$__object/explorer/pkg_version")"
+case "${state_should}" in
+	present)
+		if [ -n "${pkg_path}" ]; then
+			echo "export PKG_PATH='${pkg_path}'"
+		fi
 
-if [ -f "$__object/parameter/pkg_path" ]; then                                  
-  pkg_path="$(cat "$__object/parameter/pkg_path")"                              
-else
-  has_installurl=$(cat "${__object}/explorer/has_installurl")
-  if [ Xyes != X"${has_installurl}" ]; then
-      # there is no default PKG_PATH, try to provide one
-      pkg_path="ftp://ftp.openbsd.org/pub/OpenBSD/$os_version/packages/$machine/"
-  fi
-fi                                                                              
+		# Use this because pkg_add doesn't properly handle errors
+		cat << EOF
+status=\$(pkg_add ${pkgopts} '${pkgid}' 2>&1 || true)
 
-state_is="$(cat "$__object/explorer/pkg_state")"
-[ "$state_is" = "$state_should" ] && exit 0
+if ! pkg_info -q -I 'inst:${pkgid}' | grep -q '^${name}-${version}.*${flavor}$' 2>/dev/null
+then
+	# We didn't find the package in the list of 'installed packages', so it failed.
+	# This is necessary because pkg_add doesn't return properly
 
-case "$state_should" in
-    present)
-        # use this because pkg_add doesn't properly handle errors
-        cat << eof
-if [ X != X"${pkg_path}" ]; then
-    PKG_PATH="${pkg_path}"; export PKG_PATH
+	if [ -z "\${status}" ]; then
+		status='Failed to add package, uncaught exception.'
+	fi
+	echo "Error: \${status}" >&2
+	exit 1
 fi
-status=\$(pkg_add "$pkgopts" "$pkgid" 2>&1)
-pkg_info -q -I "inst:$pkgid" | grep -q "^${name}-${version}.*${flavor}$" 2>/dev/null
+EOF
+		echo 'installed' >> "${__messages_out}"
+		;;
 
-# We didn't find the package in the list of 'installed packages', so it failed
-# This is necessary because pkg_add doesn't return properly
-if [ \$? -ne 0 ]; then
-    if [ -z "\${status}" ]; then
-      status="Failed to add package, uncaught exception."
-    fi
-    echo "Error: \$status" >&2
-    exit 1
+	absent)
+		# Use this because pkg_delete doesn't properly handle errors
+		cat << EOF
+status=\$(pkg_delete ${pkgopts} '${pkgid}' || true)
+
+if pkg_info -q -I 'inst:${pkgid}' | grep -q '^${name}-${version}.*${flavor}' 2>/dev/null
+then
+	# We found the package in the list of 'installed packages'.
+	# This would indicate that pkg_delete failed, send the output of pkg_delete
+
+	if [ -z "\${status}" ]; then
+		status='Failed to remove package, uncaught exception.'
+	fi
+	echo "Error: \${status}" >&2
+	exit 1
 fi
-eof
-    ;;
-
-    absent)
-        # use this because pkg_add doesn't properly handle errors
-        cat << eof
-status=\$(pkg_delete "$pkgopts" "$pkgid")
-pkg_info -q -I "inst:$pkgid" | grep -q "^${name}-${version}.*${flavor}" 2>/dev/null
-
-# We found the package in the list of 'installed packages'
-# This would indicate that pkg_delete failed, send the output of pkg_delete
-if [ \$? -eq 0 ]; then
-    if [ -z "\${status}" ]; then
-      status="Failed to remove package, uncaught exception."
-    fi
-    echo "Error: \$status" >&2
-    exit 1
-fi
-eof
-   ;;
-   *)
-		echo "Unknown state: $state_should" >&2
+EOF
+		echo 'removed' >> "${__messages_out}"
+		;;
+	*)
+		echo "Unknown state: ${state_should}" >&2
 		exit 1
-   ;;
+		;;
 esac