Day 8 - bin/setup

Remember those changes we made to your README on day 1? A common area for improvement was around setup instructions.

Know what’s even better than a list of setup instructions to follow? A setup script that does them for you!

Here’s an example that I’ve used on Rails apps to good success: https://gist.github.com/r00k/ab4dce37603cd94466c9955eee88ffe1

I name this script setup and throw it in the bin directory.

Ideally, this one command is all someone needs to run before developing on your app or using your tool. But even if you can’t reach this ideal, a bin/setup script will save your users or team members time and frustration.

Today, please spend 20 minutes creating a similar script. You should be able to crib heavily from the example above, but here are a few ideas for things you might include:

  • Download and install dependencies
  • Create necessary databases
  • Seed the database with useful data, like an admin account
  • Set up useful git remotes
  • Set configuration variables / copy config files
  • Print helpful info

If you already have a setup script, try cloning your app into a new directory and running the script. Make sure it still works, and consider if you should add anything to it.

When you’re done, please chime in. Did you think of anything particularly creative to add to your script that others might want to steal? Please share!

1 Like

This one almost feels like cheating, as it was actually my scheduled task for tomorrow (Pacific time, so not quite midnight here). However, something that I only recently learned about that might help those out there using docker for db setup:

Postgres, Mysql and Mongo (perhaps others? I haven’t had reason to look) support a ‘/docker-entrypoint-initdb.d/’ folder that can be used to supply seed data.

2 Likes

Personally I just throw Docker Compose into a project for this purpose. Avoids any underlying environment / package version issues and allows collaborators/colleagues to look at how things are set up at their leisure whilst being able to get started immediately.

This was easy. I don’t remember exactly when I started to do this, but it was because of Ben’s video/post about it. Nowadays when I join a project or start a new one, I’ll make sure that bin/setup is the only thing needed to be run to get project set up in development environment. And with Rails it’s a job of few minutes :slight_smile:

1 Like

I already had a pretty complete bin/setup script, but when cloning the project to other directory I figured out that one of the configuration templates was broken :scream:

Fixed it, added some missing keys to credential templates and submitted a PR for it. :sweat_smile:

Nice task.
It made me feel like devops, when I cloned my project, ran a command, started the web server and was able to log into the app. :desktop_computer: :nerd_face:

I’d avoided this in the past as one or two of the gems we were using would consistently fail to install without errors (I think it was Nokogiri and PG, which failed because we were using Postgres.app and needed a specific path being passed in).

This doesn’t happen these days, and I’d forgotten all about setting one of these up. I’ll give it a try :grinning:

Most of my project setup stuff is in the bootstrap.sh for my vagrant setup. Nevertheless after login I still do some repetitive tasks daily.

I put those into a afterlogin.sh handling stuff like adding the right ssh key and changing to my project directory. Nothing fancy but probably gonna save myself 20-40seconds every day.

1 Like

The project I was going to do this for already had a bin/setup script, but we didn’t reference it in the README for some reason. I updated the README to use bin/setup instead of manual setup, making things simpler.

I know we have other projects that don’t have setup scripts, so if I have time this afternoon, I am going to set something up for one of them.

1 Like

GitHub has a cool standard for these kind of scripts that we follow on our projects - https://github.com/github/scripts-to-rule-them-all

They have made setting up CI much easier and because they are always being run by that system we know pretty fast if they fall out of date.

4 Likes

This one was tough, it’s the first challenge I’ve done so far where I feel like I didn’t add any real value.

In the 20 mins got part of a script to mostly create a local settings file. The way the project is currently set up it’d be very hard to automate this fully and much more than 20 minutes of work.

It’s a really good idea, but a bit too ambitious for 20 mins.

Just discovered that rails already generates a bin/setup that install all dependencies and setup the dev and test databases.

I will just add instructions to use it at my Readme. Thanks :smiley:

For anyone working on a node app, you might find that having a yarn/npm script is both easier to implement and more idiomatic than bin/setup.sh

Below is an example that gets run with yarn setup. The colorful output provided by Listr. This setup script does the same things that the setup.sh example does, but in Javascript :slight_smile:

16 AM

6 Likes

Good one. I had seen this on @ben’s Refactoring Rails course but didn’t actually do it until now.

There’s still some parts where I had to link to our Github Wiki and wait for the user to complete those steps to go on, but this should be a good improvement overall. Testing wasn’t easy though, and we’ll probably fix some issues when someone actually runs this on a vanilla setup, but that’s fine!

1 Like

I picked this up from watching thoughtbot’s upcase series a couple of years ago, and I’m very glad I did! I actually have a standing issue to create a bin/setup script in a personal project, so this came at a perfect time.

My actual favorite blog post on this is somewhat whimsical: https://robots.thoughtbot.com/shell-script-suggestions-for-speedy-setups

Solid information, separation of concerns, and thorough emoji use. I have a folder on my desktop that mimics this general walkthrough for magento and laravel installs

2 Likes

Anyone have examples that involve solving any of the following problems?

  • setup that works on linux && osx && windows
  • installing a specific version of ruby via the script
  • installing javascript build dependencies (yarn, nodejs), especially across multiple OSes

I’ve plowed ahead with a version that will only work on my preferred OS. I’m trying to do it in Ruby, because I’m a lot more confident about my future motivation to maintain it that way. WIP:

# Check for require ruby
REQUIRED_RUBY_VERSION = '2.5.0'

actual_ruby = `ruby -v`

unless actual_ruby.include? "ruby #{REQUIRED_RUBY_VERSION}"
  puts 'The wrong version of Ruby is being used.'
  puts "Required Ruby version: #{REQUIRED_RUBY_VERSION}"
  puts "Actual Ruby version: #{actual_ruby}"
  puts 'Please install and use the required Ruby version and try again.'
  exit
end

# Utility for printing shell output continuously.
def run shell_command
  IO.popen(shell_command) do |output|
    while line = output.gets do
      print line
    end
  end
end

# Install dependencies

run 'sudo apt update'
run 'sudo apt install -y default-libmysqlclient-dev pandoc curl r-base'

run 'gem install bundler' if `which bundler`.empty?
run 'bundle install'

if `nodejs -v`[0].to_i < 6
  run 'curl -sL https://deb.nodesource.com/setup_9.x | sudo -E bash -'
  run 'sudo apt install -y nodejs'
end

if `which yarn`.empty?
  run 'curl -sS https://dl.yarnpkg.com/debian/pubkey.gpg | sudo apt-key add -'
  run 'echo "deb https://dl.yarnpkg.com/debian/ stable main" | sudo tee /etc/apt/sources.list.d/yarn.list'
  run 'sudo apt update && sudo apt install -y yarn'
end

run 'yarn'
run 'sudo yarn global add phantomjs-prebuilt'
run 'sudo yarn global add bower'
run 'bower install'

puts 'ohai'

I’ve been updating my package.json to use npm scripts. No problem because it’s a really simple application (api actually) maybe when I put more things into the project…

On this project, the Makefile handles dependencies, so this was a good reminder to try the build on a fresh clone (no CI here, unfortunately). Turned up a couple of small issues, and fixed them.

1 Like

I started to look into setting up a vagrant for this project, which I always wanted to do since the build environment is hard to configure for new developers and tends to break when installing new software… This will take a while but I’ve added a ticket for us to get it done.