Skip to content

Instantly share code, notes, and snippets.

What would you like to do?
Using Shell Scripts for a Better User Experience (source for

Server scripts

This is the source for the scripts discussed in

Both scripts are in the bin/ directory of the repo that contains all the markdown documents for blog posts. Users run bin/server and everything is automatically set up for them to view a local preview of the blog. bin/server-setup is a dependency of bin/server and is never run directly by users.

Maitre-d is the name of the "blog engine" discussed in the article.

#!/usr/bin/env bash
green() { printf "\033[32m${1}\033[0m\n"; }
yellow() { printf "\033[33m${1}\033[0m\n"; }
red() { printf "\033[31m${1}\033[0m\n"; }
yellow "Setting up server (may take a while)..."
if ./bin/server-setup "$LOG_FILE"; then
green "...success! Starting server, visit http://localhost:3002"
cd tmp/maitre-d && bundle exec rails server --port 3002
red "Oops, something went wrong :/"
red "Look in tmp/server.log for the setup log"
red "If you have any questions, please ask in the #blog channel"
#!/usr/bin/env bash
# Exit if any subcommand fails
set -e
# Log everything to $LOG_FILE
exec > "$LOG_FILE" 2>&1
mkdir -p tmp
cd tmp
# Maitre-d is the blog engine
# Get the latest Maitre-d
if test -d maitre-d; then
cd maitre-d
git pull
git clone --depth=1
cd maitre-d
# Check Ruby installation
rubyversion="$(< .ruby-version)"
if ! ruby --version | grep -Fq "$rubyversion"; then
if command -v rbenv > /dev/null; then
# install via rbenv
printf 'Installing the version of Ruby for this project via rbenv...\n'
brew update
brew upgrade ruby-build || true
rbenv install
elif command -v rvm > /dev/null; then
# install via RVM
printf 'Installing the version of Ruby for this project via RVM...\n'
source "$HOME/.rvm/scripts/rvm"
rvm install "$rubyversion" && rvm use "$rubyversion"
elif command -v ruby-install > /dev/null; then
# install via ruby-install
printf 'Installing the version of Ruby for this project via ruby-install...\n'
ruby-install ruby "$rubyversion" && chruby "$rubyversion"
printf 'You do not have the correct version of Ruby installed.\n'
# Set up Ruby dependencies via Bundler
gem install bundler --conservative --no-document
bundle check || bundle install --without test
# Set up Maitre-d ENV variables to point to parent robots folder
cp .sample.env .env
echo "LOCAL_POSTS_PATH=../../source/posts/**/*.md" >> .env
# Maitre-d requires a database
bundle exec rake db:setup
# Add FILEPICKER_API_KEY if not set to the real value
if ! grep -Fq FILEPICKER_API_KEY=A .env; then
heroku join --app maitre-d-staging
heroku config:get FILEPICKER_API_KEY --shell --app maitre-d-staging >> .env
Copy link

exalted commented Oct 15, 2015

Hey @JoelQ, any reason why @thoughtbot won’t open source please? Thanks.

Copy link

pch commented Oct 16, 2015


I guess you could also do something like this (triggered whenever you modify a file in the markdown repo on your local machine, e.g. using rb-fsevent):

git status --porcelain | awk '{ print $2 }' | while read name; do cat $name | curl -X POST -d @- ''; done;

It loops through changed markdown files and POSTs their contents to the /preview action on your production server. The /preview action creates a draft from the data and allows you to preview your new post right in your production blog.

I probably messed up the command, but I hope you get the idea - which is to avoid setting up anything on local machines.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment