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

This comment has been minimized.

Copy link

exalted commented Oct 15, 2015

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


This comment has been minimized.

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
You can’t perform that action at this time.