Skip to content

Instantly share code, notes, and snippets.

@fiskr
Created April 8, 2015 16:01
Show Gist options
  • Save fiskr/b310dca30ddff4584fe5 to your computer and use it in GitHub Desktop.
Save fiskr/b310dca30ddff4584fe5 to your computer and use it in GitHub Desktop.
This script automates updates to CustomOsgiPropertyMappingService.xml when there are many environments to update.
#!/bin/bash
echo "Running runmode updates - $(date)"
# Custom OSGI Property Mapping Service files look something like
#<jcr:root xmlns:sling="http://sling.apache.org/jcr/sling/1.0" xmlns:jcr="http://www.jcp.org/jcr/1.0"
# jcr:primaryType="sling:OsgiConfig"
# mapping.map="[diy-key|value1,
# hgtv-key|value2]"
# this lets you, in the jsp, call a variable that differs according to site and environment, determined by OSGI
# e.g. in the jsp you might do something like:
# <sni-foundation:getCustomOsgiProperty var="varNameInJsp" name="varNameInOsgi"/>
# <include url="${varNameInJsp}" />
# for an OSGI mapping like:
#<jcr:root xmlns:sling="http://sling.apache.org/jcr/sling/1.0" xmlns:jcr="http://www.jcp.org/jcr/1.0"
# jcr:primaryType="sling:OsgiConfig"
# mapping.map="[diy-varNameInOsgi|/etc/clientlibs/assets/component/diy/some.xml,
# hgtv-varNameInOsgi|/etc/clientlibs/assets/component/hgtv/some.xml]"
# On DIY, the DIY XML is included; on HGTV, the HGTV XML is included
# there is one for each runmode - which means one for each environment (dev1, dev2, dev3)
# and for each type of environment (author and publish)
# e.g. for dev1 author environment the OSGI file is:
# ...hgtvcom/runmodes/config.author.dev1/com.sni.foundation.cq.services.CustomOsgiPropertyMappingService.xml
# this script lets you specify which environments you want to add new key value pairs to
# "lines" is an array of the content (the key|value pair) you want added to the Custom OSGI Property Mapping Service file
# the assumption is that the first element is a comma, because the file's last key|value pair ends as key|value]"
# the script takes this terminal ]" and replaces it with the content in the array - the first of which should be a comma and a newline
# followed by the lines of key value pairs you want to add,
# e.g.
# declare -a lines=(
# ","
# "diy-vtourskin-url|/etc/clientlibs/assets/tour/diy/vtourskin.xml,"
# "hgtv-vtourskin-url|/etc/clientlibs/assets/tour/vtourskin.xml"
# )
# the above "lines" array will take a given file, find the ]" and replace it with
# ,
# diy-vtourskin-url|/etc/clientlibs/assets/tour/diy/vtourskin.xml,
# hgtv-vtourskin-url|/etc/clientlibs/assets/tour/vtourskin.xml]"
# Note: ]" is added during the sed substitution and shouldn't be included in the last line in your array
declare -a lines=(
","
"diy-vtourskin-url|/etc/clientlibs/assets/tour/diy/vtourskin.xml,"
"hgtv-vtourskin-url|/etc/clientlibs/assets/tour/vtourskin.xml"
)
# the "envs" array specifies which configs you want to add the key value pairs in "lines" array to
declare -a envs=(
config.author.dev1
config.author.dev2
config.author.dev3
config.author.qa1
config.author.qa2
config.author.qa3
config.author.prod2
config.publish.dev1
config.publish.dev2
config.publish.dev3
config.publish.qa1
config.publish.qa2
config.publish.qa3
config.publish.prod2
)
# this is where your CQ directory lives - basically, under this directory is sni-foundation, home-hgtv-com, home-diy-com, etc.
cqDir="$HOME/cq/diy/"
# this is where your runmodes are located - under this directory are all of the environmental folders, e.g. config.author.dev2
runmodeLocation="$cqDir/home-hgtv-com/hgtvcom-config/src/main/content/jcr_root/apps/hgtvcom/runmodes"
# this is the name of the XML file you're updating - this script is only meant to update CustomOsgiPropertyMappingService.xml files
# - other files might have more than one ]", for example, or might not be under every environment you specified ...
fileName="com.sni.foundation.cq.services.CustomOsgiPropertyMappingService.xml"
# this function lets you build the "lines" array content into a string that sed can use for a substitution
function buildLine(){
# first it checks to see whether it was passed an argument
# the argument it should be passed is the indentation - what is to come before the inserted lines (spaces or tabs)
if [ $# -eq 0 ]
then
#No arguments supplied, so indent is nothing
indent=""
else
# Set indent to whatever was passed to the function
indent="$1"
fi
# we initialize or empty the variable we are going to use in the substitution (of ]" with your array content)
linesToBeAdded=""
# go through each line in the "lines" array and form a string proper for sed substitution
for line in "${lines[@]}"
do
# escape the | (pipe) symbols
line="$(echo "$line" | sed "s/\|/\\\|/g")"
# escape the / (forward slashes)
line="$(echo "$line" | sed 's/\//\\\//g')"
# if the line being evaluated is just a comma, go head and append it (don't make a newline)
if [ "$line" == "," ]
then
linesToBeAdded="$linesToBeAdded$line"
else
# the line isn't a comma, so add a \ symbol to escape the newline, and add the line you're evaluating with its indent
linesToBeAdded="$linesToBeAdded\\
$indent$line"
fi
done
#echo "built line: $linesToBeAdded"
}
#this calls "buildLine" function with the proper amount of indentation to be prepended to the lines
function buildInsert() {
# evaluate how many tabs are in the indention of the line with the terminal ]"
numberOfTabs=$((`grep -C 0 ']\"' $file | sed 's/\( *\).*/\1/' |wc -m`-1))
# if the indent has no tabs,
if [ $numberOfTabs -eq 0 ]
then
# the indent is possibly spaces - so get the number of spaces in the indentation of the line with the terminal ]"
numberOfSpaces="$(echo $((`grep -C 0 ']\"' $file | sed 's/\( *\).*/\1/' |wc -m`-1)) )"
# initialize or empty the string holding however many spaces you need
spaces=""
# if there are spaced in the indent,
if [ $numberOfSpaces -gt 0 ]
then
# build the spaces string to contain as many spaces as found in the file
# TODO: Simplify this so instead of building the string, you just pull it from the file
for (( i=0; i<$numberOfSpaces; i++ ))
do
spaces="$spaces "
done
# finally, run the buildLine function which builds the string for sed substitution
buildLine "$spaces"
else
# if no spaces or tabs are in the indent, just build the string without indention
buildLine
fi
else
# if there are tabs in the indention
# initialize or empty the string holding however many tabs you need for the indent
tabs=""
# build the tabs string to contain as many tabs as found in the indent
# TODO: Simplify this so instead of building the string, you just pull it from the file
for (( i=0; i<$numberOfTabs; i++ ))
do
tabs="$tabs "
# echo "$tabs - tabs x $i"
done
# build the string for substitution with tabs for the indent
buildLine "$tabs"
fi
}
# this is where the main action happens
# for each environment in your env array
for env in "${envs[@]}"
do
# build a filename from the combination of other variables
# - the location of the runmodes/the environment/the filname of the osgi mapping xml
file="$runmodeLocation/$env/$fileName"
# check to see if the second line in the array is in the file already
if grep --quiet ${lines[1]} $file
then
# if it is in the array, just skip over it - this block is an option to log which env has the content you're trying to add
#echo "$env : it's already in there"
echo -n "" # this makes sure there isn't a bash error because the then block doesn't have any commands
else
# the content you're adding with "lines" array isn't in the file already,
echo "adding to: $env"
# kick off the process to build the proper string for substitution
buildInsert
# finally, make the substitution with sed into a temp file
sed -e "s/]\"/$linesToBeAdded]\"/" $file > $file.temp
# move the temp file into the original file, replacing it
mv $file.temp $file
fi
done
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment