Day 10 - Create a bin/setup script

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.

Bash scripts are great but I really enjoy initialising projects with Ansible, gives you a lot of power with the simplicity of yaml notation. However, you need Ansible to be installed in order for it to work. So I can see how a bash script could be more universal as they run on any unix system out of the box.

I wonder though what people tend to do; prompt users for certain variables, or let the variables be edited in the bash script.

If you do a lot of web projects it could be worth checking out https://usepreset.dev. It allows you to create modular setup scripts for new projects. Kind of an alternative to boilerplate projects.

1 Like

A brand-new project: what better place to add a setup script?
Thanks, my colleagues will be happy with this quick install.

This is an easy one for me today! My coworkers have been diligent enough to keep our Rails bin/setup up to date. It even installs macOS dependencies from a Brewfile with brew bundle install. I have verified that the script is still running properly.

Thanks to Tuist we already have this automated with the tuist up command :rocket:
Our CI is checking if it works every day, so today’s task was an easy one for me.

On my last personal project (Golang + sqlite + webpack + tailwindcss) I had a few steps to get started. It’s easy, but when you’re away from a certain time, it is not. Thanks!

I created a new composer setup command for our backend.

Assuming you have the dependencies installed, you can now setup your database AND go through every step required to see the tests pass :heavy_check_mark:

Let’s see if @1337 is able to use it on his mac as well.

Doing mostly Rails projects, most of the work here was actually already done.

However, I found a Phoenix project that could actually use one.

Here’s the script:

#!/bin/sh

set -e

mix deps.get
mix deps.compile

mix ecto.create
mix ecto.migrate
mix run priv/repo/seeds.exs

I also found this issue comment regarding setting up useful mix aliases: Add mix task for seeding the database · Issue #8 · phoenixframework/phoenix_ecto · GitHub

Doing mostly iOS projects. Normally, I will make a script to do the project setup, dependencies installation. This makes others can easily build and run the proejct.

We develop in dockerized environment.
So our setup script is docker-compose up

My project already had a setup script (thanks to previous CQC). Updated comments a little bit, but overall looks good. And it’s used so many times. So great advice!

For the one repository that has a bigger laundry list of things to do in order to get running we now have a script that will check a developer’s system for all necessary dependencies and will tell you what is missing. Something we wanted to do for a long time but not finally had an excuse to do so. It’s quicker this way rather than consulting a readme that might get out of sync in the next pull request already.

My company started a brand new project last week and I took a good amount of time making a readme with thorough instructions for getting the local dev environment all set up. When I saw today’s challenge, I realized I had never created a setup script before. It was surprisingly easy! Within about 5 minutes I had a bash script that spun up Docker containers, configured a Laravel API, and started a React frontend application.

I’ll update our readme to have them run the setup script, but keep the instructions for manual setup for anyone that wants to do it that way.

Already had it on my project :slightly_smiling_face:

We had these in our projects too (rails default). I don’t believe they’ve ever been used; There are just two of us and haven’t had a new person in 10 years.

So spent some time updating the ansible recipe we use to build new servers.

I already have a release.sh script which creates an Elixir release. This artifact is very interesting because you can deploy it in a server without the need to install Elixir on it and with the advantage that you are not copying your source code to the client’s server.

I also have a script to copy the source code to a build server and another one to copy the release to the production server.

I have the intention to use Ansible in the future to automate this process.

Big one. At least I have created a plan (and I shall find time to test it)

What tool I may expect (python projects, devs on Windows/Linux):

  • make: better not
  • bash: better not, but if necessary
  • python: yes
  • tox: yes
  • pip: yes
  • poetry: yes
  • invoke: yes

tox can do a lot, poetry too. But sometime there are special cases, which are more complex.

invoke can do a lot, even if using only stdlib python libs.

The concept:

  • use invoke (thus only tasks.py in project root)
  • assume (at least for bootstrap tasks) only system python (3.6+)
  • README shall instruct $ invoke --list to show what actions are provided
  • use preflight checks to detect failed assumptions soon
  • if problems to execute something, simply print out what command shall be run

Open issues:

  • can globally installed invoke run anything from virtualenv?

Proposed setup actions:

  • setup-env: create virtualenv and install into it dependencies needed (possibly using poetry or tox or pip)
    • if more virtualenvs are needed, consider using one command (e.g. setup-env-py36) per virtualenv
  • test: run test suite
  • env.check: check, if env vars are properly set. Help shall provide complete instructions.
  • db.check_url: ensure, that DATABASE_URL is set and that it allows to connect to a database
  • db.alembic: either create db schema or print instructions, how to do that
  • db.backup: backup the database
  • db.restore: restore the database
  • docker.up: starts docker-compose up -d
  • docker.down: stops docker-compose down
  • docker.logs: docker-compose logs -f

Wasn’t able to finish this off in twenty minutes, and frankly, we have a bunch of prerequisites that will be hard to install via a script unfortunately. I did start on a script that will create and populate local dev databases (or validate them if the already exist). This could prove to be very useful!

Nice. It never striked my mind that I could write script to install system dependencies in the setup!

I’ve been actively working on this in a few Rails applications, to help ease non-Ruby experts into development. I’m using bin/setup in conjunction with devcontainers in VS Code. For the most part, a stock bin/setup goes a long way. The one thing I think I want to add is an interactive way to set some environment configs.