Skip to content

Instantly share code, notes, and snippets.

@isalew
Last active March 14, 2017 22:28
Show Gist options
  • Save isalew/f7699cd03750e5cfc73b2a280f5df184 to your computer and use it in GitHub Desktop.
Save isalew/f7699cd03750e5cfc73b2a280f5df184 to your computer and use it in GitHub Desktop.
Support utility for SFDX to zip and unzip static resources.
#!/bin/bash
# -- HEADER --------------------------------------------------------------------
# Author: [email protected]
# Date: 2017.03.02
# Description: Zips and unzips .resource files for local editing
# -- ENVIRONMENT VARS ----------------------------------------------------------
PROGNAME="$(basename ${BASH_SOURCE[0]})"
PROGALIAS="${PROGNAME//.sh/}"
PROGNAMESPACE='force:resource'
# -- CONFIG VARS ---------------------------------------------------------------
PROJECT_DIR="$(git rev-parse --show-toplevel)"
CONFIG_FILE="sfdx-workspace.json"
CONFIG_FILE_DIR="$PROJECT_DIR/$CONFIG_FILE"
PACKAGE_DIR="$(cat $CONFIG_FILE_DIR | jq -r '.PackageDirectories[] | select(.Default == true) | .Path')"
BUNDLE_PATH_KEY="StaticResourceBundlesPath"
BUNDLE_PATH_DEFAULT="resource-bundles"
BUNDLE_PATH="$(cat $CONFIG_FILE_DIR | jq --arg k ${BUNDLE_PATH_KEY} -r '.[($k)]')"
RESOURCE_PATH_KEY="StaticResourcesPath"
RESOURCE_PATH_DEFAULT="${PACKAGE_DIR}/main/default/staticresources"
RESOURCE_EXT="resource"
RESOURCE_META_EXT="-meta.xml"
RESOURCE_PATH="$(cat $CONFIG_FILE_DIR | jq --arg k ${RESOURCE_PATH_KEY} -r '.[($k)]')"
CONTENT_TYPE=""
# -- FORMAT VARS ---------------------------------------------------------------
NORM=`tput sgr0`
BOLD=`tput bold`
REV=`tput smso`
TAB=" "
# -- INPUT VARS ----------------------------------------------------------------
SHORTOPTS="hn:c:r:b:"
LONGOPTS="help,name:,contentType:,resourcePath:,bundlePath:"
INPUT="$@"
COMMAND=""
NAME=""
HELP=false
HELP_COMPACT=false
# -- USAGE ---------------------------------------------------------------------
function inputs {
echo
echo "${TAB}${TAB}${BOLD}Inputs:${NORM}"
echo
echo "${TAB}${TAB}COMMAND force:resource:$COMMAND"
echo "${TAB}${TAB}--help $HELP"
echo "${TAB}${TAB}--name $NAME"
echo "${TAB}${TAB}--contentType $CONTENT_TYPE"
echo "${TAB}${TAB}--resourcePath $RESOURCE_PATH"
echo "${TAB}${TAB}--bundlePath $BUNDLE_PATH"
}
function help {
USAGE="${TAB}"
COMMAND_VARS=$1
COMMAND_DESCRIPTION=$2
if [ -z "$COMMAND" ]
then
COMMAND="[command]"
COMMAND_VARS="[--command-specific-options]"
fi
# usage
if [ $HELP_COMPACT = false ];
then
echo
USAGE+="${BOLD}Usage:${NORM} $PROGALIAS "
else
USAGE+="${TAB}"
fi
USAGE+="$PROGNAMESPACE:$COMMAND $COMMAND_VARS"
echo "$USAGE"
# description
if [ $HELP_COMPACT = false ] && [ -n "$COMMAND_DESCRIPTION" ]
then
echo
echo "${TAB}${TAB}$COMMAND_DESCRIPTION"
fi
# command list
if [ $COMMAND = "[command]" ]
then
HELP_COMPACT=true
echo
echo "${TAB}${TAB}${BOLD}Commands:${NORM}"
echo
# add new command functions here
new_bundle
bundle
unbundle
configure
HELP_COMPACT=false
fi
# option list
if [ $HELP_COMPACT = false ]
then
echo
echo "${TAB}${TAB}${BOLD}Options:${NORM}"
echo
echo "${TAB}${TAB}-h, --help view command usage"
echo "${TAB}${TAB}-n, --name name of resource"
echo "${TAB}${TAB}-c, --contentType MIME type of resource"
echo "${TAB}${TAB}-r, --resourcePath path to bundled resource or default location"
echo "${TAB}${TAB}-b, --bundlePath path to unbundled resource or default location"
# inputs
fi
}
# -- INPUT PROCESSING ----------------------------------------------------------
OPTS='$(getopt --name $PROGNAME --options $SHORTOPTS --longoptions $LONGOPTS -- "$@")'
if [ $? != 0 ]; then echo "Failed parsing options." >&2 ; exit 1 ; fi
eval set -- "$OPTS"
shift 7
while true; do
case $1 in
-h|--help) HELP=true; shift ;;
-n|--name) NAME="$2"; shift 2 ;;
-c|--contentType) CONTENT_TYPE="$2"; shift 2 ;;
-r|--resourcePath) RESOURCE_PATH="$2"; shift 2 ;;
-b|--bundlePath) BUNDLE_PATH="$2"; shift 2 ;;
force:resource*) COMMAND="$(echo $1 | sed "s/$PROGNAMESPACE://")"; shift ;;
--) shift; break ;;
*) break ;;
esac
done
if [ "$COMMAND" = "$PROGNAMESPACE" ]; then COMMAND=""; fi
if [ "$BUNDLE_PATH" == "null" ]; then BUNDLE_PATH=""; fi
if [ "$RESOURCE_PATH" == "null" ]; then RESOURCE_PATH=""; fi
# -- FUNCTIONS -----------------------------------------------------------------
function new_bundle {
COMMAND="new"
COMMAND_VARS="<-n|--name> [-b|bundlePath]"
COMMAND_DESCRIPTION="Creates a new bundle ready to deploy."
if [ -z "$NAME" ] || [ -z "$BUNDLE_PATH" ]
then
help "$COMMAND_VARS" "$COMMAND_DESCRIPTION"
else
# create resource-bundles/bundle-name.resource
BUNDLE="$BUNDLE_PATH/$NAME"
echo "Creating resource bundle: $BUNDLE"
mkdir -p "$BUNDLE"
fi
}
function bundle {
COMMAND="bundle"
COMMAND_VARS="<-n|--name> [-c|--contentType] [-r|--resourcePath]"
COMMAND_DESCRIPTION="Zips a bundle directory into a static resource."
if [ -z "$CONTENT_TYPE" ]; then CONTENT_TYPE="application/zip"; fi
if [ -z "$NAME" ] || [ -z "$RESOURCE_PATH" ]
then
help "$COMMAND_VARS" "$COMMAND_DESCRIPTION"
else
# TODO: Parse name for dynamic filepaths
# FILENAME="$(echo $NAME | ref | cut -d'/' -f-1 | rev)"
# create bundle-name.resource-meta.xml
RESOURCE_META="$RESOURCE_PATH/$NAME.$RESOURCE_EXT$RESOURCE_META_EXT"
echo "Creating resource meta.xml: $RESOURCE_META"
RESOURCE_META_XML="<?xml version=\"1.0\" encoding=\"UTF-8\"?>
<StaticResource xmlns=\"http://soap.sforce.com/2006/04/metadata\">
<cacheControl>Private</cacheControl>
<contentType>${CONTENT_TYPE}</contentType>
</StaticResource>"
echo -e "$RESOURCE_META_XML" > "$RESOURCE_META"
# create bundle-name.resource
echo "${TAB}Bundling static resource $NAME"
# TODO: check if bundle is directory or file
cd "$BUNDLE_PATH/$NAME"
zip -r "../TMP_ZIP" .*
cd "$PROJECT_DIR"
mv "$PROJECT_DIR/$BUNDLE_PATH/TMP_ZIP.zip" "$RESOURCE_PATH/$NAME.$RESOURCE_EXT"
fi
# leave deploy for standard sfdx
}
function unbundle {
COMMAND="unbundle"
COMMAND_VARS="<-n|--name> [-b|--bundlePath]"
COMMAND_DESCRIPTION="Unzips a static resource into a bundle directory."
if [ -z "$NAME" ] || [ -z "$BUNDLE_PATH" ]
then
help "$COMMAND_VARS" "$COMMAND_DESCRIPTION"
else
RESOURCE="$RESOURCE_PATH/$NAME.$RESOURCE_EXT"
echo "${TAB}Unbundling Static Resource: $NAME"
# TODO: get bundle contentType
# CONTENT_TYPE="$(xmllint --xpath \"//*[name()='contentType']/text())\""
new_bundle
unzip "$RESOURCE" -d "$BUNDLE_PATH/$NAME"
fi
}
function configure {
OLD_COMMAND=$COMMAND
COMMAND="configure"
COMMAND_VARS="[-r|--resourcePath] [-b|--bundlePath]"
COMMAND_DESCRIPTION="Sets target and source locations for bundle directories."
if [[ (-z "$RESOURCE_PATH" && -z "$BUNDLE_PATH") || $HELP_COMPACT == true ]]
then
help "$COMMAND_VARS" "$COMMAND_DESCRIPTION"
return
fi
if [ -n "$RESOURCE_PATH" ]
then
echo "${TAB}Setting Resource Parent Directory: $RESOURCE_PATH"
TMP="$(mktemp $CONFIG_FILE.temp)"
cat $CONFIG_FILE | jq --arg k ${RESOURCE_PATH_KEY} --arg v ${RESOURCE_PATH} '. + { ($k) : $v }' > $TMP
cat $TMP
mv "$TMP" "$CONFIG_FILE"
fi
if [ -n "$BUNDLE_PATH" ]
then
echo "${TAB}Setting Bundle Parent Directory: $BUNDLE_PATH"
TMP="$(mktemp $CONFIG_FILE.temp)"
cat $CONFIG_FILE | jq --arg k ${BUNDLE_PATH_KEY} --arg v ${BUNDLE_PATH} '. + { ($k) : $v }' > $TMP
cat $TMP
mv "$TMP" "$CONFIG_FILE"
fi
COMMAND=$OLD_COMMAND
}
# ------------------------------------------------------------------------------
if [ -z "$COMMAND" ]
then
help
exit
fi
if [[ $COMMAND = "configure" ]]
then
configure
exit
fi
if [[ -z "$RESOURCE_PATH" ]]
then
echo
echo "${TAB}Error: No input directory specified for resource bundles."
read -n1 -p "${TAB}Accept default? ($RESOURCE_PATH_DEFAULT) [y,n] " doit
case $doit in
y|Y)
RESOURCE_PATH=$RESOURCE_PATH_DEFAULT
configure
;;
*)
configure
exit;;
esac
fi
if [[ -z "$BUNDLE_PATH" ]]
then
echo
echo "${TAB}Error: No output directory specified for resource bundles."
read -n1 -p "${TAB}Accept default? ($BUNDLE_PATH_DEFAULT) [y,n] " doit
case $doit in
y|Y)
BUNDLE_PATH=$BUNDLE_PATH_DEFAULT
configure
;;
*)
configure
exit;;
esac
fi
if [[ $COMMAND = "new" ]]
then
new_bundle
exit
fi
if [[ $COMMAND = "bundle" ]]
then
bundle
exit
fi
if [[ $COMMAND = "unbundle" ]]
then
unbundle
exit
fi
echo
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment