3 # Author: Kevin Wentworth
4 # Author: Chris Koeritz
6 # This contains a bunch of reusable functions that help out in managing websites.
8 # This script is sourced, and relies on the value of WORKDIR, which should
9 # point at the directory where the site management scripts are stored,
10 # especially this one.
12 source "$FEISTY_MEOW_SCRIPTS/core/launch_feisty_meow.sh"
14 # get our configuration loaded, if we know the config file.
15 # if there is none, we will use our default version.
16 export SITE_MANAGEMENT_CONFIG_FILE
17 if [ -z "$SITE_MANAGEMENT_CONFIG_FILE" ]; then
18 SITE_MANAGEMENT_CONFIG_FILE="$WORKDIR/config/default.app"
19 echo "Site management config file was not set. Using default:"
20 echo " $SITE_MANAGEMENT_CONFIG_FILE"
23 # load in at least the default version to get us moving.
24 source "$SITE_MANAGEMENT_CONFIG_FILE"
25 test_or_die "loading site management configuration from: $SITE_MANAGEMENT_CONFIG_FILE"
27 # configure feisty revision control to ignore vendor folders.
28 export NO_CHECKIN_VENDOR=true
30 # tests that the main storage folder for apps exists.
31 function check_application_dir()
33 local appdir="$1"; shift
34 if [ ! -d "$appdir" ]; then
35 echo "Creating the apps directory: $appdir"
37 test_or_die "Making apps directory when not already present"
41 # tries to find an appropriate config file for the application.
42 function locate_config_file()
44 local app_dirname="$1"; shift
46 local configfile="$WORKDIR/config/${app_dirname}.app"
47 echo "config file?: $configfile"
48 if [ ! -f "$configfile" ]; then
49 # this is not a good config file. we can't auto-guess the config.
51 There is no specific site configuration file in:
53 We will continue onward using the default and hope that this project follows
54 the standard pattern for cakephp projects."
55 # we'll pull in the default config file we set earlier; this will
56 # reinitialize some variables based on the app name.
58 # they gave us a valid config file. let's try using it.
59 export SITE_MANAGEMENT_CONFIG_FILE="$configfile"
62 # try to load the config.
63 source "$SITE_MANAGEMENT_CONFIG_FILE"
64 test_or_die "loading site management configuration from: $SITE_MANAGEMENT_CONFIG_FILE"
68 # this function will seek out top-level directories in the target directory passed in.
69 # if there is only one directory, then it is returned (in the app_dirname variable).
70 # otherwise, the user is asked which directory to use.
71 # important: this sets a global variable app_dirname to the application's directory name.
72 function find_app_folder()
74 local appsdir="$1"; shift
76 # throw away any prior value so no confusion arises.
79 # count number of directories... if exactly one, then choose it.
80 numdirs=$(count_directories "$appsdir")
82 if [ $numdirs -eq 0 ]; then
84 echo "There are no directories in the application directory:"
86 echo "Please create a directory for the site storage, based on the application"
87 echo "name that you want to work on. Or you can just pass the directory name"
88 echo "on the command line, e.g.:"
89 echo " $(basename $0) turtle"
92 elif [ $numdirs -eq 1 ]; then
93 app_dirname="$(basename $(find "$appsdir" -mindepth 1 -maxdepth 1 -type d) )"
94 test_or_die "Guessing application folder"
96 # if more than one folder, force user to choose.
97 # Reference: https://askubuntu.com/questions/1705/how-can-i-create-a-select-menu-in-a-shell-script
99 PS3='Please pick a folder for site initialization: '
100 options=( $(find "$appsdir" -mindepth 1 -maxdepth 1 -type d -exec basename {} ';') "Quit")
101 select app_dirname in "${options[@]}"; do
103 "Quit") echo ; echo "Quitting from the script."; exit 1; ;;
104 *) echo ; echo "You picked folder '$app_dirname'" ; break; ;;
107 if [ -z "$app_dirname" ]; then
108 echo "The folder was not provided. This script needs a directory name"
109 echo "within which to initialize the site."
114 test_app_folder "$appsdir" "$app_dirname"
115 test_or_die "Testing application folder: $app_dirname"
117 echo "Application folder is: $app_dirname"
120 # ensures that the app directory name is valid.
121 function test_app_folder()
123 local appsdir="$1"; shift
124 local dir="$1"; shift
126 local combo="$appsdir/$dir"
128 if [ ! -d "$combo" ]; then
129 echo "Creating app directory: $combo"
131 test_or_die "Making application directory when not already present"
134 locate_config_file "$dir"
137 # eases some permissions to enable apache to write log files and do other shopkeeping.
138 function fix_site_perms()
140 local app_dir="$1"; shift
142 local site_dir="$app_dir/$CHECKOUT_DIR_NAME"
144 if [ -f "$site_dir/bin/cake" ]; then
145 sudo chmod -R a+rx "$site_dir/bin/cake"
146 test_or_die "Enabling execute bit on cake binary"
149 if [ ! -d "$site_dir/logs" ]; then
150 mkdir "$site_dir/logs"
151 test_or_die "Creating logs directory"
153 sudo chmod -R g+w "$site_dir/logs"
154 test_or_die "Enabling group write on site's Logs directory"
156 if [ ! -d "$site_dir/tmp" ]; then
157 mkdir "$site_dir/tmp"
158 test_or_die "Creating tmp directory"
160 sudo chmod -R g+w "$site_dir/tmp"
161 test_or_die "Enabling group write on site's tmp directory"
164 # tosses out any cached object data that originated from the database.
165 function clear_orm_cache()
167 local site_dir="$1"; shift
169 if [ -f "$site_dir/bin/cake" ]; then
170 # flush any cached objects from db.
171 "$site_dir/bin/cake" orm_cache clear
172 test_or_die "Clearing ORM cache"
176 # updates the revision control repository passed in. this expects that the
177 # repo will live in a folder called "checkout_dirname" under the app path,
178 # which is the standard for our deployed sites.
179 # important: this also sets a global variable called site_store_path to the full
180 # path of the application.
181 function update_repo()
183 local full_app_dir="$1"; shift
184 local checkout_dirname="$1"; shift
185 local repo_root="$1"; shift
186 local repo_name="$1"; shift
188 echo here are parms in update repo:
189 var full_app_dir checkout_dirname repo_root repo_name
191 # forget any prior value, since we are going to validate the path.
192 unset site_store_path
194 pushd "$full_app_dir" &>/dev/null
195 test_or_die "Switching to our app dir '$full_app_dir'"
197 local complete_path="$full_app_dir/$checkout_dirname"
199 # see if the checkout directory exits. the repo_found variable is set to
200 # non-empty if we find it and it's a valid git repo.
202 if [ -d "$checkout_dirname" ]; then
203 # checkout directory exists, so let's check it.
204 pushd "$checkout_dirname" &>/dev/null
205 test_or_die "Switching to our checkout directory: $checkout_dirname"
207 # ask for repository name (without .git).
208 if git rev-parse --git-dir > /dev/null 2>&1; then
209 # this is a valid git repo.
213 # we don't consider the state of having the dir exist but the repo be wrong as good.
214 if [ -z "$repo_found" ]; then
215 echo "There is a problem; this folder is not a valid repository:"
216 echo " $full_app_dir"
217 echo "This script cannot continue unless the git repository is valid."
223 if [ ! -z "$repo_found" ]; then
224 # a repository was found, so update the version here and leave.
225 echo "Repository $repo_name exists. Updating it."
227 test_or_die "Recursive checkout on: $complete_path"
229 # clone the repo since it wasn't found.
230 echo "Cloning repository $repo_name now."
231 git clone "$repo_root/$repo_name.git" $checkout_dirname
232 test_or_die "Git clone of repository: $repo_name"
235 #not doing this here since powerup uses this and has no sudo.
236 #fix_site_perms "$complete_path"
239 # construct the full path to where the app will actually live.
240 site_store_path="$complete_path"
245 # this function goes to the directory specified and makes it right with
246 # composer install. this is as opposed to composer update, which could
248 function composer_repuff()
250 local site_store_path="$1"; shift
252 pushd "$site_store_path" &>/dev/null
253 test_or_die "Switching to our app dir '$site_store_path'"
255 echo "Updating site with composer..."
258 test_or_die "Composer installation step on '$site_store_path'."
262 dir="$site_store_path/$CHECKOUT_DIR_NAME/vendor/siteavenger/avcore"
263 if [ -d "$dir" ]; then
264 echo "Running avcore database migrations..."
265 logfile="$TMP/problem-avcore_db_migration-$(date_stringer).log"
266 ./bin/cake migrations migrate -p Avcore &>"$logfile"
267 if [ $? -ne 0 ]; then
268 echo "** FAILED: Database migrations for avcore. Check log file in: $logfile"
269 # we keep going, because some sites aren't ready for this yet.
272 echo "Database for avcore migrated."
281 # this function creates the links needed to make the site function properly given our
282 # various dependencies and infrastructure.
283 function create_site_links()
285 local site_store_path="$1"; shift
286 local theme_name="$1"; shift
288 echo "Creating symbolic links for site assets..."
290 # jump into the site path so we can start making relative links.
291 pushd "$site_store_path" &>/dev/null
292 test_or_die "Switching to our app dir '$site_store_path'"
294 pushd webroot &>/dev/null
296 # remove all symlinks that might plague us.
297 find . -maxdepth 1 -type l -exec rm -f {} ';'
298 test_or_die "Cleaning out links in webroot"
300 # link in the avcore plugin.
301 make_safe_link "../vendor/siteavenger/avcore/webroot" avcore
303 # make the link for our theme as a lower-case version of the theme.
304 themelower=${theme_name,,}
305 make_safe_link "../plugins/$theme_name/webroot" "$themelower"
307 # link in any favicon files.
308 if [ -d "../plugins/$theme_name/favicon" ]; then
310 for fave in "../plugins/$theme_name/favicon"/*; do
311 make_safe_link "$fave" .
315 # get back out of webroot.
318 # hop up a level above where we had been.
321 # link 'public' to webroot.
322 if [ -L public ]; then
323 # public is a symlink.
325 test_or_die "Removing public directory symlink"
326 elif [ -d public ]; then
327 # public is a folder with default files.
330 test_or_die "Removing public directory and contents"
333 # create the main 'public' symlink
335 make_safe_link $CHECKOUT_DIR_NAME/webroot public
336 test_or_die "Creating link to webroot called 'public'"
338 #hmmm: public/$themelower/im will be created automatically by system user with appropriate permissions
340 echo Created symbolic links.
346 # fetches composer to make sure it's up to date.
347 # (if powerup runs, composer install doesn't update git origin.)
348 function update_composer_repository()
350 local site_store_path="$1"; shift
352 pushd "$site_store_path" &>/dev/null
354 if git config remote.composer.url &>/dev/null; then
356 echo "Updated the composer repository."
358 echo "No composer repository was found for updating."
362 # fixes the ownership for a site avenger or php application.
363 # this almost certainly will require sudo capability, if there are any ownership problems
364 # that need to be resolved.
365 function fix_appdir_ownership()
367 local appsdir="$1"; shift
368 local dir="$1"; shift
370 local combo="$appsdir/$dir"
372 # go with the default user running the script.
374 if [ ! -z "$user_name" -a "$user_name" != "root" ]; then
375 echo "Chowning the apps folder to be owned by: $user_name"
376 #hmmm: have to hope for now for standard group named after user
377 sudo chown -R "$user_name:$user_name" "$combo"
378 test_or_die "Chowning $combo to be owned by $user_name"
380 echo "user name failed checks for chowning, was found as '$user_name'"
384 #probably not enough for path!
385 fix_site_perms "$combo"