I found this shell script
# Run SwiftLint
START_DATE=$(date +"%s")
SWIFT_LINT=/usr/local/bin/swiftlint
# Run SwiftLint for given filename
run_swiftlint() {
local filename="${1}"
if [[ "${filename##*.}" == "swift" ]]; then
#${SWIFT_LINT} autocorrect --path "${filename}"
${SWIFT_LINT} lint --path "${filename}"
fi
}
if [[ -e "${SWIFT_LINT}" ]]; then
echo "SwiftLint version: $(${SWIFT_LINT} version)"
# Run for both staged and unstaged files
git diff --name-only | while read filename; do run_swiftlint "${filename}"; done
git diff --cached --name-only | while read filename; do run_swiftlint "${filename}"; done
else
echo "${SWIFT_LINT} is not installed."
exit 0
fi
END_DATE=$(date +"%s")
DIFF=$(($END_DATE - $START_DATE))
echo "SwiftLint took $(($DIFF / 60)) minutes and $(($DIFF % 60)) seconds to complete."
Over here
https://github.com/realm/SwiftLint/issues/413#issuecomment-184077062
Which worked pretty well till I updated my computer to the new M1 chip.
According to this blog
https://www.anotheriosdevblog.com/installing-swiftlint-on-a-m1/
We should change the location of the path.
I suspect it has something to do with the location SwiftLint is installed:
However I'm not to familiar with home-brew or shell script to get it working.
Home-brew location has changed on the new Macs.
changing
SWIFT_LINT=/usr/local/bin/swiftlint
to
SWIFT_LINT=/opt/homebrew/bin/swiftlint
Fixed the issue
Related
I am trying to write a bash script which checks if there are any commits of a repository and returns a message. Here is the script so far.
MY_PATH="C:/test"
cd "$MY_PATH"
git clone https://github.com/test-repo/docker-react.git
cd "docker-react"
git checkout master
if [[ -n "`git log --pretty=format: --name-only --since="200 days ago" | sort | uniq`" ]]
then
echo -e No Commits last 2 days
else
echo -e Commits available
fi
When I execute this code it always show commits available even when I change the days.
Where am I going wrong?
That looks like a bash script, which would be interpreted by the Git for Windows bash shell.
It means it should be checked with ShellCheck, which would then recommend:
#!/bin/bash
MY_PATH="C:/test"
cd "$MY_PATH" || exit
git clone https://github.com/test-repo/docker-react.git
cd "docker-react" || exit
git checkout master
if [[ -n "$(git log --pretty=format: --name-only --since="200 days ago" | sort | uniq)" ]]
then
echo -e No Commits last 2 days
else
echo -e Commits available
fi
Not yet ideal: ideally, it would check if the repository is not already cloned. But it should work better.
I wrote this bash script to remove the old version of a Mac application and install the new version. It all works well, except it doesn't seem to delete the application before installing the new one - instead, it seems to write over the top of it, which is causing some issues when you try to launch the application. Wondering where I'm going wrong in my script - any help would be much appreciated.
#!/bin/sh
#Script to remove the old version of 8x8 Virtual Office and the install the latest version.
APP=/Applications/8x8\ -\ Virtual\ Office.app
VERSION=$(defaults read /Applications/8x8\ -\ Virtual\ Office.app/Contents/Info | grep CFBundleShortVersionString | cut -c35-39)
#See Script options in JSS for $4 value
LATEST="$4"
pid=$(ps -fe | grep '8x8 - Virtual Office' | grep -v grep | awk '{print $2}')
if test -e "$APP" ; then
if [ "$VERSION" \< "$LATEST" ] ; then
echo "8x8 Virtual Office $VERSION found"
echo "Application needs updating..."
if [[ -n $pid ]]; then
echo "Quitting application first..."
kill $pid
sleep 5s
echo "Removing old version..."
rm -f $APP
sleep 5s
echo "Installing new version..."
jamf policy -event install88
else
echo "Application not running, removing old version..."
rm -f $APP
sleep 5s
echo "Installing new version..."
jamf policy -event install88
exit 0
fi
else
echo "No update required"
exit 0
fi
else
echo "8x8 Virtual Office not found, installing..."
jamf policy -event install88
exit 0
fi
APP=/Applications/8x8\ -\ Virtual\ Office.app
Your path contains spaces. So remove command should be rm -f "$APP"
Demo:
:=>APP=/Applications/8x8\ -\ Virtual\ Office.app
:=>echo $APP
/Applications/8x8 - Virtual Office.app
:=>rm $APP
rm: cannot remove '/Applications/8x8': No such file or directory
rm: cannot remove '-': No such file or directory
rm: cannot remove 'Virtual': No such file or directory
rm: cannot remove 'Office.app': No such file or directory
:=>rm "$APP"
rm: cannot remove '/Applications/8x8 - Virtual Office.app': No such file or directory
:=>
In the above demo when we execute rm $APP rm command is taking 4 arguments Applications/8x8 , - , Virtual ,Office.app becasue of spaces in path.
`
I want to set up a jekyll blog on a shared server. When I try to install Jekyll I get "You don't have write permissions". How do I fix this without root or sudo?
More detail:
I have space on a shared server and don't have root access. I couldn't install Ruby, though the hosting company installed it upon my request.
When I try to install Jekyll I use
user#hosting.org [~]# gem install jekyll
and this is the response I get:
ERROR: While executing gem ... (Gem::FilePermissionError)
You don't have write permissions into the /usr/lib/ruby/gems/1.8 directory.
I have seen different suggestions for changing the GEMPATH which I have tried including
export GEM_PATH=/home/user/something
But even after doing so
gem env
still results in
GEM PATHS:
- /usr/lib/ruby/gems/1.8
- /home/user/.gem/ruby/1.8
Any tips? Is it possible to install jekyll without root or sudo priviliges or am I just making some rookie PATH error?
I didn't find the answer for a while. on the #jekyll IRC a user pointed me at the Arch wiki and I discovered that the thing is to force the install as a single user:
gem install jekyll --user-install
This worked for me in MAC
1.Place the gems in user's home folder.Add below commands in .bashrc or .zshrc
export GEM_HOME=$HOME/gems
export PATH=$HOME/gems/bin:$PATH
2.Use installation command
gem install jekyll bundler
3.Verify Installation
jekyll -v
Use the documentation for detailed reference
https://jekyllrb.com/docs/troubleshooting/#no-sudo
The reason for that is the default Ruby that gets shipped with Mac (I am assuming this, but this is true for some distributions of Linux as well) installs gems to a user folder that needs permissions to modify the contents. This is not a Ruby error to be precise.
That said, since Ruby 1.8.7 is not supported any more, you'd be better off avoiding using it and using one of the alternative ruby version managing tools like chruby or rvm or rbenv. (I'd vote for chruby btw). The documentation is pretty dense for all those. The authors are quite helpful in resolving issues if you do end up having one or more.
... am I just making some rookie PATH error?
Yes, I think so... I'm not sure why you're assigning GEM_PATH, I haven't needed to, and think ya perhaps wanted GEM_HOME instead. Though things may have changed since then and the current now that this'll be posted at.
TLDR
I usually write something such as...
## Ruby exports for user level gem & bundle installs
export GEM_HOME="${HOME}/.gem"
export PATH="${GEM_HOME}/bin:${PATH}"
... to somewhere like ~/.bash_aliases for each user that'll be authenticating to a server.
Then within any git-shell-commands script, for an authenticated user that makes use of Gems, source the above settings prior.
I want to set up a jekyll blog on a shared server. When I try to install Jekyll I get "You don't have write permissions". How do I fix this without root or sudo?
Might be worth checking out a project I've published a little while ago. It's been written and tested on Linux systems with Bash versions >= 4 if you sort out Mac feel free to make a PR. Otherwise, for shared servers, the least amount of fuss may be had by sticking with Xenial, from Ubuntu, or the freshest Raspberry flavored Debian.
Here's some snippets that should aid in automating an answer to your question...
/usr/local/etc/Jekyll_Admin/shared_functions/user_mods/jekyll_gem_bash_aliases.sh
#!/usr/bin/env bash
jekyll_gem_bash_aliases(){ ## jekyll_gem_bash_aliases <user>
local _user="${1:?No user name provided}"
local _home="$(awk -F':' -v _user="${_user}" '$0 ~ "^" _user ":" {print $6}' /etc/passwd)"
if [ -f "${_home}/.bash_aliases" ]; then
printf '%s/.bash_aliases already exists\n' "${_home}" >&2
return 1
fi
## Save new user path variable for Ruby executables
su --shell "$(which bash)" --command 'touch ${HOME}/.bash_aliases' --login "${_user}"
tee -a "${_home}/.bash_aliases" 1>/dev/null <<'EOF'
## Ruby exports for user level gem & bundle installs
export GEM_HOME="${HOME}/.gem"
export PATH="${GEM_HOME}/bin:${PATH}"
EOF
su --shell "$(which bash)" --command 'chmod u+x ${HOME}/.bash_aliases' --login "${_user}"
printf '## %s finished\n' "${FUNCNAME[0]}"
}
The above is used by one of three scripts that make use of sudo level permissions, specifically jekyll_usermod.sh... but don't get too caught-up with grokking all the contortions that I'm asking of Bash, because the moral of the above function's story is that it writes something like...
## Ruby exports for user level gem & bundle installs
export GEM_HOME="${HOME}/.gem"
export PATH="${GEM_HOME}/bin:${PATH}"
... to somewhere like /srv/bill/.bash_aliases which'll get sourced in git-shell-commands scripts and/or other shared functions for account setup like the following...
/usr/local/etc/Jekyll_Admin/shared_functions/user_mods/jekyll_user_install.sh
#!/usr/bin/env bash
jekyll_user_install(){ ## jekyll_user_install <user>
local _user="${1:?No user name provided}"
su --shell "$(which bash)" --login "${_user}" <<'EOF'
source "${HOME}/.bash_aliases"
mkdir -vp "${HOME}"/{git,www}
## Initialize Jekyll repo for user account
_old_PWD="${PWD}"
mkdir -vp "${HOME}/git/${USER}"
cd "${HOME}/git/${USER}"
git init .
git checkout -b gh-pages
_ruby_version="$(ruby --version)"
printf 'Ruby Version: %s\n' "${_ruby_version}"
_ruby_version="$(awk '{print $2}' <<<"${_ruby_version%.*}")"
_ruby_version_main="${_ruby_version%.*}"
_ruby_version_sub="${_ruby_version#*.}"
if [[ "${_ruby_version_main}" -ge '2' ]] && [[ "${_ruby_version_sub}" -ge '1' ]]; then
gem install bundler -v '< 2'
gem install jekyll -v '3.8.5'
bundle init
bundle install --path "${HOME}/.bundle/install"
bundle add jekyll-github-metadata github-pages
bundle exec jekyll new --force --skip-bundle "${HOME}/git/${USER}"
bundle install
else
echo 'Please see to installing Ruby verion >= 2.4' >&2
echo 'Hints may be found at, https://jekyllrb.com/docs/installation/' >&2
fi
git config receive.denyCurrentBranch updateInstead
cat >> "${HOME}/git/${USER}/.gitignore" <<EOL
# Ignore files and folders generated by Bundler
Bundler
vendor
.bundle
Gemfile.lock
EOL
git add --all
git -c user.name="${USER}" -c user.email="${USER}#${HOSTNAME}" commit -m "Added files from Bundler & Jekyll to git tracking"
cd "${_old_PWD}"
EOF
local _exit_status="${?}"
printf '## %s finished\n' "${FUNCNAME[0]}"
return "${_exit_status}"
}
Note, .bash_aliases is arbitrary as far as file naming, well so long as one is consistent, it could even be more explicit via something like .gems_aliases; end-users need not know what happens behind the curtains to make this magic happen in other words.
... which'll hopefully show one clear method of causing gem install someThing and related commands to search the user's installed packages first. Though in case another example is needed...
~/git-shell-commands/jekyll-init
#!/usr/bin/env bash
__SOURCE__="${BASH_SOURCE[0]}"
while [[ -h "${__SOURCE__}" ]]; do
__SOURCE__="$(find "${__SOURCE__}" -type l -ls | sed -n 's#^.* -> \(.*\)#\1#p')"
done
__DIR__="$(cd -P "$(dirname "${__SOURCE__}")" && pwd)"
__NAME__="${__SOURCE__##*/}"
__AUTHOR__='S0AndS0'
__DESCRIPTION__='Initializes new Git repository with a gh-pages branch'
## Provides 'failure'
# source "${__DIR__}/shared_functions/failure"
# trap 'failure "LINENO" "BASH_LINENO" "${BASH_COMMAND}" "${?}"' ERR
## Provides: argument_parser <arg-array-reference> <acceptable-arg-reference>
source "${__DIR__}/shared_functions/arg_parser"
## Provides: git_add_commit <string>
source "${__DIR__}/shared_functions/git_shortcuts"
## Provides: __license__ <description> <author>
source "${__DIR__}/shared_functions/license"
usage(){
_message="${1}"
_repo_name="${_repo_name:-repository-name}"
cat <<EOF
## Usage
# ssh ${USER}#host-or-ip ${__NAME__} ${_git_args[#]:-$_repo_name}
#
# ${__DESCRIPTION__}
#
# --quite
# Git initializes quietly
#
# --shared
# Allow git push for group $(groups | awk '{print $1}')
#
# --template=<path>
# Template git repository that git init should pull from
#
# ${_repo_name}
# Name of repository to internalize or add Jekyll gh-pages branch to
#
## For detailed documentation of the above options.
## See: git help init
#
# --clean
# Remove non-git related files and directories from gh-pages branch prior to
# initializing Jekyll related files. This allows for files from previous branch
# to remain separate from files being tracked on the gh-pages branch.
#
# -l --license
# Shows script or project license then exits
#
# -h --help help
# Displays this message and exits
#
## The following options maybe used to modify the generated _config.yml file
#
# --title ${_title}
# --email ${_email}
# --twitter-username ${_twitter_username}
# --github-username ${_github_username}
EOF
if [ -n "${_message}" ] && [[ "${_message}" != '0' ]]; then
printf 'Error - %s\n' "${_message}" >&2
fi
}
_args=("${#:?# No arguments provided try: ${__NAME__} help}")
_valid_args=('--help|-h|help:bool'
'--license|-l|license:bool'
'--quiet:bool'
'--clean:bool'
'--shared:bool'
'--template:path'
'--title:print'
'--email:print'
'--twitter-username:posix'
'--github-username:posix'
'--repo-name:posix-nil')
argument_parser '_args' '_valid_args'
_exit_status="$?"
_git_args=()
if ((_quiet)); then _git_args+=('--quiet'); fi
if ((_shared)); then _git_args+=('--shared'); fi
if [ -n "${_template}" ]; then _git_args+=("--template='${_template}'"); fi
if [ -n "${_repo_name}" ]; then _git_args+=("${_repo_name}"); fi
## Set defaults for some variables if not already set
_github_username="${_github_username:-$USER}"
if [ -z "${_title}" ]; then
for _word in ${_repo_name//[-_]/ }; do
if [[ "${#_word}" -ge '4' ]]; then
_temp_title+=("${_word^}")
else
_temp_title+=("${_word}")
fi
done
_title="${_temp_title[#]}"
fi
_bundle_path="${HOME}/.bundle/install"
if ((_help)) || ((_exit_status)); then
usage "${_exit_status}"
exit "${_exit_status}"
elif ((_license)); then
__license__ "${__DESCRIPTION__}" "${__AUTHOR__}"
exit 0
fi
if [ -z "${_repo_name}" ]; then
usage 'missing repository name argument!'
exit "1"
fi
_git_path="${HOME}/git/${_repo_name:?No repository name provided}"
_old_PWD="${PWD}"
if [ -d "${_git_path}" ]; then cd "${_git_path}"; fi
_git_dir="$(git rev-parse --git-dir 2>/dev/null)"
if [[ "${_git_path}/${_git_dir}" == "${_git_path}/.git" ]]; then
printf '# Skipping git init, path already tracked by git: %s\n' "${_git_preexisting_dir}"
elif [[ "${_git_path}/${_git_dir}" == "${_git_path}/." ]]; then
echo '# Bare git repository detected, cannot install Jekyll to that right now'
exit 1
else
if [ -e "${HOME}/git-shell-commands/git-init" ]; then
"${HOME}/git-shell-commands/git-init" ${_git_args[#]}
else
cd "${HOME}/git" || exit 1
git init ${_git_args[#]}
fi
fi
cd "${_git_path}" || exit 1
_git_branches="$(git branch --list)"
_orig_branch="$(awk '/\*/{print $2}' <<<"${_git_branches}")"
_pages_branch="$(awk '/gh-pages/{print $2}' <<<"${_git_branches}")"
if [ -n "${_pages_branch}" ]; then
printf '# There is already a pages branch %s for repository %s\n' "${_pages_branch}" "${_repo_name}"
exit 1
fi
git_add_commit "Added files on ${_orig_branch} prior to installing Bundler & Jekyll to gh-pages branch"
git checkout -b gh-pages
if [[ "$(git config receive.denyCurrentBranch)" != 'updateInstead' ]]; then
git config receive.denyCurrentBranch updateInstead
fi
if ((_clean)); then
for _path in ${_git_path}/*; do
case "${_path}" in
*'.git') [[ -d "${_path}" ]] && continue ;;
*'.gitignore') [[ -f "${_path}" ]] && continue ;;
esac
git rm -rf "${_path}"
done
git_add_commit 'Cleaned gh-pages branch of files from parent branch'
fi
modify_config_yml(){
if ! [ -f "${_git_path}/_config.yml" ]; then
printf 'Error - no Jekyll config file found under %s\n' "${_git_path}" >&2
return 1
fi
if [ -n "${_title}" ]; then
sed -i "/title:/ { s#:[a-zA-Z 0-9]*#: ${_title}#; }" "${_git_path}/_config.yml"
fi
if [ -n "${_email}" ]; then
sed -i "/email:/ { s#:[a-zA-Z 0-9]*#: ${_email}#; }" "${_git_path}/_config.yml"
fi
if [ -n "${_twitter_username}" ]; then
sed -i "/_twitter_username:/ { s#:[a-zA-Z 0-9]*#: ${_twitter_username}#; }" "${_git_path}/_config.yml"
fi
if [ -n "${_github_username}" ]; then
sed -i "/github_username:/ { s#:[a-zA-Z 0-9]*#: ${_github_username}#; }" "${_git_path}/_config.yml"
fi
if [[ "${_repo_name}" != "${_github_username}" ]]; then
tee -a "${_git_path}/_config_baseurl.yml" 1>/dev/null <<EOF
# Use base URL to simulate GitHub pages behaviour
baseurl: "${_repo_name}"
EOF
fi
}
source "${HOME}/.bash_aliases"
bundle init || exit "${?}"
bundle install --path "${_bundle_path}"
bundle add jekyll
bundle exec jekyll new --force --skip-bundle "${_git_path}"
modify_config_yml
bundle install
cat >> "${_git_path}/.gitignore" <<EOF
# Ignore files and folders generated by Bundler
Bundler
vendor
.bundle
Gemfile.lock
EOF
git_add_commit 'Added files from Bundler & Jekyll to git tracking'
[[ "${_old_PWD}" == "${_git_path}" ]] || cd "${_old_PWD}"
printf '# Clone %s via: git clone %s#domain_or_ip:%s\n' "${_repo_name}" "${USER}" "${_git_path//${HOME}\//}"
printf '# %s finished\n' "${__NAME__}"
... which also shows how to bundle install someThing to somewhere.
Good luck with the publishing and perhaps comment if ya get stuck.
I have the following problem. I need to organize automatic upload to deploy server from svn repository, but with some feautures.
There is how I wrote it:
# $1 - project; $2 - version (optional)
# rm -rf $projectDir
if [ "$2" == '' ]; then
svn export $trunk $projectDir --force >> $log
version=`svn info $trunk | grep Revision | awk '{print$2}'`
svn copy $trunk $tags/$version -m "created while uploading last version of $1"
echo "New stable version #$version of $1 is created
Uploading to last version is completed successfully"
else
version=$2
svn export $tags/$version/ $projectDir --force >> $log
echo "Revert to version #$version is completed successfully"
fi
echo $version > $projectDir/version
chown -R $1:$1 $projectDir
But svn export doesn't delete deleted via svn files, so I need to clean directory before export every time. It's not good.
Before this, I work with checkout for deploy like this:
svn co $trunk >> $log
cp -ruf trunk/* $projectDir
svn info $trunk | grep Revision > $projectDir/version
chown -R $project:$project $projectDir
echo "uploading finished"
This work very well and very very faster (it changes only changed files) than the export, but:
without automatic tag creating;
without opportunity for nice reverting.
In my last script co doesn't work, because it trying to checkout in one directory from different repository directories (trunk/some tag), which isn't real.
So, question:
Can I relocate project before checkout?
Can I find the diff with co version and existing version before export?
What can I do with diff result? (remove unneeded files after export?)
Thanks in advance.
Have you evaluated Capistrano? It can do a lot of what you're trying to achieve.
For the basis for the solution was taken following code:
It's simpler and fully solves the problem as for me.
if [ "$2" == '' ]; then
version=`svn info ${trunk} | grep Revision | awk '{print$2}'`
if [ `cat ${projectWWW}/version` == "${version}" ]; then
resultMessage="Project is up to date"
else
svn co ${trunk} ${projectRoot}/co >> ${log}
cp -ruf ${projectRoot}/co/ ${projectRoot}/releases/${version}
chown -R $1:$1 ${projectRoot}/releases/${version}
resultMessage="New stable version #$version of $1 is created
Uploading to last version is completed successfully"
fi
else
version=$2
resultMessage="Revert to version #$version is completed successfully"
fi
ln -s ${projectRoot}/releases/${version} ${projectWWW}
echo ${version} > ${projectWWW}/version
echo ${resultMessage} >> ${log}
I'm working with App Engine and I'm thinking about using the LESS CSS extension in my next project. There's no good LESS CSS library written in Python so I went on with the original Ruby one which works great and out of the box. I'd like App Engine to execute lessc ./templates/css/style.less before running the development server and before uploading the files to the cloud. What is the best way to automate this? I'm thinking:
#run.sh:
lessc ./templates/css/style.less
.gae/dev_appserver.py --use_sqlite .
And
#deploy.sh
lessc ./templates/css/style.less
.gae/appcfg.py update .
Am I on the correct path or is there a more elegant way of doing things, perhaps at the appcfg.py level?
Thanks.
One option is to use the javascript version of Less and hence do the less-to-css conversion in the browser.. simply upload your less formatted file (see http://lesscss.org/ for details).
Alternately, I do the conversion (first with less, now I use sass) in a deploy script which does a number of things
checks that my source code control has no outstanding files checked out (uncommited changes)
joins and minifies my .js code (and runs jslint over it) into a single file
generates other content (including stamping the source code control version as a version number into certain key files and as a parameter on some files to avoid caching issues) so my main page pulls in scripts with URLs such as "allmysource.js?v=585".. the file might be static but the added params force cache invalidation
calls appcfg to perform the upload and checks the return code
makes some calls to the real site with wget to check the previously generated files are actually returned, by checking they're stamped with the expected version
applies another source code control tag to say that the intended version was successfully deployed
My script also accepts a "-preview" flag in which case it doesn't actually do the upload, but reports the version control comments for what's changed since the previous deployment.
me#here $ ./deploy -preview
Deployment preview...
Would deploy v596 to the production site (currently v593, previously v587)
594 Fix blah blah blah for X Y Z
595 New feature nah nah nah
596 Update help pages
This is pretty handy as a reminder of what I need to put in things like a changelog
I plan to also expand it so that I can, as part of my source code control, add any code that needs running once only when deployed (eg database schema changes) and know that it'll be automatically run when I next deploy a new version.
Essence of the script below as people asked... it doesn't show my "check code, generate, join, and minify" as that's another script... I realise that the original question was asking about that step of course :) but you can see where you'd add the call to generate CSS etc
#!/bin/sh
function abort () {
echo
echo "ERROR: $1"
echo "$2"
exit 99
}
function warn () {
echo
echo "WARNING: $1"
echo "$2"
}
# Overrides the Gentoo eselect mechanism to force the python version the GAE scripts expect
export EPYTHON=python2.5
# names of tags used to label bzr versions
CURR_DTAG=deployed
PREV_DTAG=prevDeployed
# command line options
PREVIEW=0
IGNORE_BZR=0
# These next few vars are set to values to identify my site, insert your own values here...
APPID=your_gae_appid_here
ADMIN_EMAIL=your_admin_email_address_here
SRCDIR=directory_to_deploy
CHECK_URL=url_of_page_to_retrive_that_does_upload_initialisation
for ARG; do
if [[ "$ARG" == "-preview" ]]; then
echo "Deployment preview..."
PREVIEW=1
fi
if [[ "$ARG" == "-force" ]]; then
echo "Ignoring the fact some files may not be committed to bzr..."
IGNORE_BZR=1
fi
done
echo
# check bzr for uncommited changed
BSTATUS=`bzr status`
if [[ "$BSTATUS" != "" ]]; then
if [[ "$IGNORE_BZR" == "0" ]]; then
abort "There are uncommited changes - commit/revert/ignore all files before deploying" "$BSTATUS"
else
warn "There are uncommited changes" "$BSTATUS"
fi
fi
# get version of numbers of last deployed etc
currver=`bzr log -l1 --line | sed -e 's/: .*//'`
lastver=`bzr log -rtag:${CURR_DTAG} --line | sed -e 's/: .*//'`
prevver=`bzr log -rtag:${PREV_DTAG} --line | sed -e 's/: .*//'`
lastlog=`bzr log -l 1 --line gae/changelog | sed -e 's/: .*//'`
RELEASE_NOTES=`bzr log --short --forward -r $lastver..$currver \
| perl -ne '$ver = $1 if /^ {0,4}(\d+) /; print " $ver $_" if ($ver and /^ {5,}\w/)' \
| grep -v "^ *$lastver "`
LOG_NOTES=`bzr log --short --forward -r $lastlog..$currver \
| perl -ne '$ver = $1 if /^ {0,4}(\d+) /; print " $ver $_" if ($ver and /^ {5,}\w/)' \
| grep -v "^ *$lastlog "`
# Crude but old habit - BUGBUGBUG is a marker in the code for things to be fixed before deployment
echo "Checking code for outstanding issues before deployment"
BUGSTATUS=`grep BUGBUGBUG js/*js`
if [[ "$BUGSTATUS" != "" ]]; then
if [[ "$IGNORE_BZR" == "0" ]]; then
abort "There are outstanding BUGBUGBUGs - fix them before deploying" "$BUGSTATUS"
else
warn "There are outstanding BUGBUGBUGs" "$BUGSTATUS"
fi
fi
echo
echo "Deploy v$currver to the production site (currently v$lastver, previously v$prevver)"
echo "$RELEASE_NOTES"
echo
if [[ "$currver" -gt "$lastlog" && "$lastver" -ne "$lastlog" ]]; then
echo "Changes since the changelog was last updated"
echo "$LOG_NOTES"
echo
fi
if [[ "$IGNORE_BZR" == "0" && $lastver -ge $currver ]]; then
abort "There don't appear to be any changes to deploy..."
fi
if [[ "$PREVIEW" == "1" ]]; then
exit 0
fi
$EPYTHON -c "import ssl" \
|| abort "$EPYTHON can't find ssl module for $EPYTHON - download it from pypi and install with the inbuilt setup.py"
# REMOVED - call to my script that calls jslint, generates files and compresses JS etc
# || abort "Generation of code failed"
/opt/google_appengine/appcfg.py --email=$ADMIN_EMAIL -v -A $APPID update $SRCDIR \
|| abort "Appcfg failed - upload presumably incomplete"
# move the tags to show we deployed properly
bzr tag -r $lastver --force ${PREV_DTAG}
bzr tag -r $currver --force ${CURR_DTAG}
echo
echo "Production site updated from v$lastver to v$currver (in turn from v$prevver)"
echo
echo "Now visiting $CHECK_URL to upload the source to the database"
# new version doesn't seem to always be there (may be caching by the webserver etc) to be uploaded into the database.. try again just in case
for cb in $RANDOM $RANDOM $RANDOM $RANDOM ; do
prodver=`wget $CHECK_URL?_cb=$cb -q -O - | perl -ne 'print $1 if /^\s*Rev #(\d+)\s*$/'`
if [[ "$currver" == "$prodver" ]]; then
echo "OK: New version $prodver successfully deployed"
exit 0
fi
echo "Retrying the upload of source to the database"
sleep 5
done
abort "The new source doesn't seem to be loading into the database" "Try 'wget $CHECK_URL?_cb=$RANDOM -q -O -'"
It's not particularly big or clever, but it automates the upload job