Skip to content

Instantly share code, notes, and snippets.

@jifeon
Last active November 9, 2015 09:29
Show Gist options
  • Save jifeon/7fa1342a46e1d0f0c5e9 to your computer and use it in GitHub Desktop.
Save jifeon/7fa1342a46e1d0f0c5e9 to your computer and use it in GitHub Desktop.
Patch for assetic:dump --watch wraping it into inotifywait. This behaviour allows to reduce CPU load, cause by default assetic check freshness of collections every second. Run script with -h for more information.
#!/bin/bash
NOCOLOR='\e[0m'
REDCOLOR='\e[37;41m'
function usage {
code=${1:-0}
echo "Usage: $0 [-h] [-p] [-r] [-f] [-c] [-d css|js|f|b] [-e dev|prod] [project_name]
where:
-h Show this help text
-p Show the list of available projects
-r Reactive run :) Do not touch assetic on run. Use only if files have not changed from previouse run
-f Clean your cache of assetic settings before running assetic
-c Clear both application cache and compiled static
-d Marks some cache as dirty. It also clear saved asset collections for all options
except 'b'. Possible dirty places are:
js - Your awesome JavaScripts in compiled/js folder
css - Styles in compiled/css
f - A la front: js and css
b - Back. Script will clear app/var/cache/. In this case saved asset collections
will not be cleaned automatically. To force the script clean them, use -f option
-e Set environment. dev by default
dev - Developing environment
prod - Production environment
project_name - The name of project that you want to run assetic for. By default project in
the current folder will be used. Use the -p option to see whole list of
available projects."
exit ${code}
}
projects_path=~/www40
function show_available_projects {
code=${1:-0}
echo "List of available projects:"
ls -1 ${projects_path}
exit ${code}
}
while getopts ":frhpcd:e:" opt; do
case ${opt} in
h)
usage
;;
p)
show_available_projects
;;
f)
echo "Suppose your asset collections caches are very dirty.."
clean_dump_cache=1
;;
r)
reactive=1
;;
c)
clean=1
;;
d)
clean=1
dirty=$OPTARG
;;
e)
if [ $OPTARG == "prod" ]; then
prod=1
fi
;;
[?])
echo "Invalid option: -$OPTARG" >&2
usage 1
;;
esac
done
shift $(($OPTIND-1))
project_name=${1:-${PWD##*/}}
base_path=${projects_path}/${project_name}
console_path=${base_path}/app/console
if [[ ! -e ${base_path} ]]; then
echo "Invalid path to project" >&2
show_available_projects 1
fi
if [[ ${prod} ]]; then
echo "Building application in production mode"
# We can't pass the path to web directory if we use core:install instead of assets:install...
# ...
cd ${base_path}
${console_path} core:install --symlink web --env=prod --no-debug &&
echo -e "$REDCOLOR Open your dev with app.php$NOCOLOR"
cd -
exit 0
fi
if [[ ! `which inotifywait` ]]; then
echo -e "$REDCOLOR You must install 'inotifywait'.$NOCOLOR"
echo " # sudo apt-get install inotify-tools"
exit 1
fi
user_name=$(whoami)
# A file to store orinal output of assetic. It used for getting all resources location for the first time. After that
# reources can be found in the cached file - $asset_paths_file
assetic_output=$(mktemp)
asset_paths_file=/tmp/assetic_output_${user_name}_${project_name}
inotify_pid_file=$(mktemp)
inotify_output=$(mktemp)
inotify_pid=
function onExit {
kill ${inotify_pid}
if [[ -e ${inotify_pid_file} ]]; then
kill $(cat ${inotify_pid_file})
fi
rm -f ${assetic_output} ${inotify_pid_file} ${inotify_output}
}
trap "onExit" EXIT
# Assetic runs with --watch option in purpose to force it save the cache of dumped assets. In that conditions assetic
# does not finish its process and hangs up, so we run it as a background job and wait until if writes a file with cache.
# We also use a very long refresh period to prevent assetic from any chance to run twice
function dump_assets {
echo "Collecting assets..."
local opts=$1
local output=$2
if [[ ${output} ]]; then
exec 3>${output}
else
exec 3>&1
fi
php ${console_path} assetic:dump --watch --period=100000 ${opts} >&3 &
local assetic_pid=$!
(inotifywait -q -m --format=%w%f -e modify -e create /tmp/ & echo $! >&3) 3>${inotify_pid_file} | while read chnages; do
if [[ ${chnages} == *assetic_watch_* ]]; then
echo "Assetic has written the cache, so kill it"
# We really need to wait for a while here to allow php complete writing. Otherwise the file with cached
# assets could be corrapted.
sleep 1
kill $(cat ${inotify_pid_file})
kill ${assetic_pid}
break
fi
done
exec 3>&-
}
if [ ${clean} ]; then
echo "Your assets cache is so dirty!"
# Often if we need clear the back it is not necessare to clear assets
if [[ ${dirty} != "b" ]]; then
clean_dump_cache=1
fi
case ${dirty} in
css)
echo "clearing css..."
rm -rf ${base_path}/web/compiled/css/*
echo "done"
;;
js)
echo "clearing js..."
rm -rf ${base_path}/web/compiled/js/*
echo "done"
;;
f)
echo "clearing front..."
rm -rf ${base_path}/web/compiled/*
echo "done"
;;
b)
echo "clearing back..."
rm -rf ${base_path}/app/var/cache/*
echo "done"
;;
*)
echo "clearing back..."
rm -rf ${base_path}/app/var/cache/*
echo "clearing front..."
rm -rf ${base_path}/web/compiled/*
echo "done"
esac
fi
echo "Check for the asset paths cache file $asset_paths_file"
if [[ -e ${asset_paths_file} && ! ${clean_dump_cache} ]]; then
echo "Getting assets location from the cache"
asset_paths=$(cat ${asset_paths_file})
if [ ! "$reactive" ]; then
dump_assets
fi
else
echo "Dumping all assets first time. Please be patient and just wait, wait, wait..."
tail -f ${assetic_output} &
dump_out_pid=$!
# --force to prevent from using cache and -v to log source paths
dump_assets "--force -v" ${assetic_output}
kill ${dump_out_pid}
asset_paths=$(cat ${assetic_output} | grep Resources | sed -e "s/\(.*Resources\).*/\1/" | sort | uniq)
rm -f ${assetic_output}
echo ${asset_paths} > ${asset_paths_file}
fi
if [ ! "$asset_paths" ]; then
echo -e "$REDCOLOR Assets paths have not collected. Try to run with -f option$NOCOLOR"
exit 1
fi
echo "Assets are located in:"
echo ${asset_paths} | sed "s/ /\n/g"
inotifywait -r -m -e modify -e move -e create -e delete ${asset_paths} > ${inotify_output} &
inotify_pid=$!
while true; do
modified=$(cat ${inotify_output})
> ${inotify_output}
if [[ ${modified} ]]; then dump_assets; fi
sleep 1
done
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment