mirror of
https://github.com/thoughtbot/shoulda-matchers.git
synced 2022-11-09 12:01:38 -05:00
Update contributor docs, add maintainer docs
* Move section on documentation from README to CONTRIBUTING * Add a setup script that contributors and maintainers can use to set up a dev environment [skip ci]
This commit is contained in:
parent
40a86cc2bb
commit
ff14d6ffc4
4 changed files with 589 additions and 130 deletions
218
CONTRIBUTING.md
218
CONTRIBUTING.md
|
@ -1,92 +1,172 @@
|
|||
# Contributing to shoulda-matchers
|
||||
# Contributing to Shoulda Matchers
|
||||
|
||||
We love contributions from the community! Here's a quick guide to making a pull
|
||||
request.
|
||||
We've put a lot of work into making improvements to Shoulda Matchers, but we
|
||||
always welcome changes and improvements from the community!
|
||||
|
||||
1. If you haven't contributed before, please read and understand the [Code of
|
||||
Conduct].
|
||||
|
||||
1. Ensure that you have a [working Ruby environment].
|
||||
|
||||
1. Fork the repo on GitHub, then clone it to your machine.
|
||||
|
||||
1. Now that you've cloned the repo, navigate to it and install dependencies by
|
||||
running:
|
||||
|
||||
bundle install
|
||||
|
||||
1. All tests should be passing, but it's a good idea to run them anyway
|
||||
before starting any work:
|
||||
|
||||
bundle exec rake
|
||||
|
||||
1. If you're adding functionality or fixing a bug, you'll want to add a
|
||||
failing test for the issue first.
|
||||
|
||||
1. Now you can implement the feature or bugfix.
|
||||
|
||||
1. Since we only accept pull requests with passing tests, it's a good idea to
|
||||
run the tests again. Since you're probably working on a single file, you can
|
||||
run the tests for that file with the following command:
|
||||
|
||||
bundle exec appraisal <Appraisal name> rspec <path of test file to run>
|
||||
|
||||
You can find a list of valid Appraisals by running:
|
||||
|
||||
bundle exec rake appraisal:list
|
||||
|
||||
(If you're familiar with Zeus, you can also run unit tests by running `zeus
|
||||
start` in one shell, and then running the following in another:)
|
||||
|
||||
zeus rspec <path of test file to run>
|
||||
|
||||
In any case, to run the entire test suite again, say:
|
||||
|
||||
bundle exec rake
|
||||
If you'd like to propose a change to the gem, whether it's a fix for a problem
|
||||
you've been running into or an idea for a new feature you think would be useful,
|
||||
here's how the process works:
|
||||
|
||||
1. [Read and understand the Code of Conduct](#code-of-conduct).
|
||||
1. Fork this repo and clone your fork to somewhere on your machine.
|
||||
1. [Ensure that you have a working environment](#setting-up-your-environment).
|
||||
1. Read up on the [architecture of the gem](#architecture), [how to run
|
||||
tests](#running-tests), and [the code style we use in this
|
||||
project](#code-style).
|
||||
1. Cut a new branch and write a failing test for the feature or bugfix you plan
|
||||
on implementing.
|
||||
1. [Make sure your branch is well managed as you go
|
||||
along](#managing-your-branch).
|
||||
1. [Update the inline documentation if you're making a change to the
|
||||
API](#documentation).
|
||||
1. [Refrain from updating the changelog.](#a-word-on-the-changelog)
|
||||
1. Finally, push to your fork and submit a pull request.
|
||||
|
||||
At this point, you're waiting on us. We may suggest some changes to make to your
|
||||
code to fit within the project style, or discuss alternate ways of addressing
|
||||
the issue in question. When we're happy with everything, we'll bring your
|
||||
changes into master. Now you're a contributor!
|
||||
Although we maintain the gem in our free time, we try to respond within a day or
|
||||
so. After submitting your PR, we may give you feedback. For instance, we may
|
||||
suggest some changes to make to your code to fit within the project style or
|
||||
discuss alternate ways of addressing the issue in question. Assuming we're happy
|
||||
with everything, we'll bring your changes into master!
|
||||
|
||||
## Addendum: Setting up your environment
|
||||
---
|
||||
|
||||
### Installing Ruby
|
||||
## Code of Conduct
|
||||
|
||||
shoulda-matchers is only compatible with Ruby 2.x. A `.ruby-version` is included
|
||||
in the repo, so if you're using one of the Ruby version manager tools, then you
|
||||
should be using (or have been prompted to install) the latest version of Ruby.
|
||||
If not, you'll want to do that.
|
||||
If this is your first time contributing, please read the [Code of Conduct]. We
|
||||
want to create a space in which everyone is allowed to contribute, and we
|
||||
enforce the policies outline in this document.
|
||||
|
||||
[working Ruby environment]: #addendum-setting-up-your-environment
|
||||
[Code of Conduct]: https://thoughtbot.com/open-source-code-of-conduct
|
||||
[execjs]: https://github.com/sstephenson/execjs
|
||||
|
||||
### Linux-specific instructions
|
||||
## Setting up your environment
|
||||
|
||||
#### Debian/Ubuntu
|
||||
The setup script will install all dependencies necessary for working on the
|
||||
project:
|
||||
|
||||
Run this command to install necessary dependencies:
|
||||
|
||||
```
|
||||
sudo apt-get install -y ruby-dev libpq-dev libsqlite3-dev nodejs
|
||||
```bash
|
||||
bin/setup
|
||||
```
|
||||
|
||||
#### RedHat
|
||||
## Architecture
|
||||
|
||||
Run this command to install necessary dependencies:
|
||||
This project follows the typical structure for a gem: code is located in `lib`
|
||||
and tests are in `spec`.
|
||||
|
||||
All of the matchers are broken up by the type of example group they apply to:
|
||||
|
||||
* `{lib,spec/unit}/shoulda/matchers/action_controller*` for ActionController
|
||||
matchers
|
||||
* `{lib,spec/unit}/shoulda/matchers/active_model*` for ActiveModel matchers
|
||||
* `{lib,spec/unit}/shoulda/matchers/active_record*` for ActiveRecord matchers
|
||||
* `{lib,spec/unit}/shoulda/matchers/independent*` for matchers that can be used
|
||||
in any example group
|
||||
|
||||
There are other files in the project, of course, but there are likely the ones
|
||||
that you'll be interested in.
|
||||
|
||||
In addition, tests are broken up into two categories:
|
||||
|
||||
* `spec/unit`
|
||||
* `spec/acceptance`
|
||||
|
||||
A word about the tests, by the way: they're admittedly the most complicated part
|
||||
of this gem, and there are a few different strategies that we've introduced at
|
||||
various points in time to set up objects for tests across all specs, some of
|
||||
which are old and some of which are new. The best approach for writing tests is
|
||||
probably to copy an existing test in the same file as where you want to add a
|
||||
new test.
|
||||
|
||||
## Code style
|
||||
|
||||
We follow a derivative of the [unofficial Ruby style guide] created by the
|
||||
Rubocop developers. You can view our Rubocop configuration [here], but here are
|
||||
some key differences:
|
||||
|
||||
* Use single quotes for strings.
|
||||
* When breaking up methods across multiple lines, place the `.` at the end of
|
||||
the line instead of the beginning.
|
||||
* Don't use conditional modifiers (i.e. `x if y`); place the beginning and
|
||||
ending of conditionals on their own lines.
|
||||
* Use an 80-character line-length except for `describe`, `context`, `it`, and
|
||||
`specify` lines in tests.
|
||||
* For arrays, hashes, and method arguments that span multiple lines, place a
|
||||
trailing comma at the end of the last item.
|
||||
* Collection methods are spelled `detect`, `inject`, `map`, and `select`.
|
||||
|
||||
[unofficial Ruby style guide]: https://github.com/rubocop-hq/ruby-style-guide
|
||||
[here]: .rubocop.yml
|
||||
|
||||
## Running tests
|
||||
|
||||
### Unit tests
|
||||
|
||||
Unit tests are the most common kind of tests in the gem. They exercise matcher
|
||||
code file by file in the context of a real Rails application. This application
|
||||
is created and loaded every time you run `rspec`. Because of this, it can be
|
||||
expensive to run individual tests. To save time, the best way to run unit tests
|
||||
is by using [Zeus].
|
||||
|
||||
[Zeus]: https://github.com/burke/zeus
|
||||
|
||||
You'll want to start by running `zeus start` in one shell. Then in another
|
||||
shell, instead of using `bundle exec rspec` to run tests, you'll use `bundle
|
||||
exec zeus rspec`. So for instance, you might say:
|
||||
|
||||
```
|
||||
sudo yum install -y ruby-devel postgresql-devel sqlite-devel zlib-devel
|
||||
bundle exec zeus rspec spec/unit/shoulda/matchers/active_model/validate_inclusion_of_matcher_spec.rb
|
||||
```
|
||||
|
||||
Then, install one of the JavaScript runtimes supported by [execjs]. For
|
||||
instance, to install node.js:
|
||||
### Acceptance tests
|
||||
|
||||
The acceptance tests exercise matchers in the context of a real Ruby or Rails
|
||||
application. Unlike unit tests, this application is set up and torn down for
|
||||
each test.
|
||||
|
||||
Whereas you make use of Zeus to run unit tests, you make use of Appraisal for
|
||||
acceptance tests. [Appraisal] lets you run tests against multiple versions of
|
||||
Rails and Ruby, and in fact, this is baked into the test suite. This means that
|
||||
if you're trying to run a single test file, you'll need to specify which
|
||||
appraisal to use. For instance, you can't simply say:
|
||||
|
||||
[Appraisal]: https://github.com/thoughtbot/appraisal
|
||||
|
||||
```
|
||||
sudo su
|
||||
curl -sL https://rpm.nodesource.com/setup | bash -
|
||||
yum install -y nodejs
|
||||
bundle exec rspec spec/acceptance/active_model_integration_spec.rb
|
||||
```
|
||||
|
||||
Instead, you need to say
|
||||
|
||||
```
|
||||
bundle exec appraisal 5.1 rspec spec/acceptance/active_model_integration_spec.rb
|
||||
```
|
||||
|
||||
## Managing your branch
|
||||
|
||||
* Use well-crafted commit messages, providing context if possible. [tpope's
|
||||
guide] was a wonderful piece on this topic when it came out and we still find
|
||||
it to be helpful even today.
|
||||
* Squash "WIP" commits and remove merge commits by rebasing. We try to keep our
|
||||
commit history as clean as possible.
|
||||
|
||||
[tpope's guide]: https://tbaggery.com/2008/04/19/a-note-about-git-commit-messages.html
|
||||
|
||||
## Documentation
|
||||
|
||||
As you navigate the codebase, you may notice that each class and method in the
|
||||
public API is prefaced with inline documentation, which can be viewed
|
||||
[online][rubydocs]. This documentation is written and generated using
|
||||
[YARD][yard].
|
||||
|
||||
[rubydocs]: https://matchers.shoulda.io/docs
|
||||
[yard]: https://github.com/lsegal/yard
|
||||
|
||||
We ensure that the documentation is up to date before we issue a release, but
|
||||
sometimes we don't catch everything. So if your changes end up extending or
|
||||
updating the API, it's a big help if you can update the documentation to match
|
||||
and submit those changes in your PR.
|
||||
|
||||
## A word on the changelog
|
||||
|
||||
You may also notice that we have a changelog in the form of [NEWS.md](NEWS.md).
|
||||
You may be tempted to include changes to this in your branch, but don't worry
|
||||
about this -- we'll take care of it!
|
||||
|
|
250
MAINTAINING.md
Normal file
250
MAINTAINING.md
Normal file
|
@ -0,0 +1,250 @@
|
|||
# Maintaining Shoulda Matchers
|
||||
|
||||
As maintainers of the gem, this is our guide. Most of the steps and guidelines
|
||||
in the [Contributing](CONTRIBUTING.md) document apply here, including how to set
|
||||
up your environment, write code to fit the code style, run tests, craft commits
|
||||
and manage branches. Beyond this, this document provides some details that would
|
||||
be too low-level for contributors.
|
||||
|
||||
## Communication
|
||||
|
||||
We use a combination of methods to communicate with each other:
|
||||
|
||||
* In planning major releases, it can be helpful to create a **new issue**
|
||||
outlining the changes as well as steps needed to launch the release. This
|
||||
serves both as an announcement to the community as well as an area to keep a
|
||||
checklist.
|
||||
* To track progress for the next release, **GitHub milestones** are useful.
|
||||
* To track progress on the movement of issues, [**labels**](#addendum-labels)
|
||||
are useful.
|
||||
* To communicate small-scale changes, **pull requests** are effective, as
|
||||
mentioned above.
|
||||
* To communicate large-scale changes or explain topics, **email** is best.
|
||||
|
||||
## Managing the community
|
||||
|
||||
As anyone who has played a sim game before, it's important to make your patrons
|
||||
happy. We do this by:
|
||||
|
||||
* Answering questions from members of the community
|
||||
* Closing stale issues and feature requests
|
||||
* Keeping the community informed by ensuring that the changelog is up to date
|
||||
* Ensuring that the inline documentation, as well as the docsite, is kept up to
|
||||
date
|
||||
|
||||
## Workflow
|
||||
|
||||
We generally follow [GitHub Flow]. The `master` branch is the main line, and all
|
||||
branches are cut from and get merged back into this branch. Generally, the
|
||||
workflow is as follows:
|
||||
|
||||
[GitHub Flow]: https://help.github.com/articles/github-flow/
|
||||
|
||||
* Cut a feature or bugfix branch from this branch.
|
||||
* Upon completing a branch, create a PR and ask another maintainer to approve
|
||||
it.
|
||||
* Try to keep the commit history as clean as possible. Before merging, squash
|
||||
"WIP" or related commits together and rebase as needed.
|
||||
* Once your PR is approved and you've cleaned up your branch, you're free to
|
||||
merge it in.
|
||||
|
||||
## Architecture
|
||||
|
||||
Besides the matchers, there are files in `lib` which you may need to reference
|
||||
or update:
|
||||
|
||||
* `lib/shoulda/matchers/doublespeak*` -- a small handrolled mocking library
|
||||
which is used by the `permit` matcher
|
||||
* `lib/shoulda/matchers/util*` -- extra methods which are used in various places
|
||||
to detect library versions, wrap/indent text, and more
|
||||
|
||||
## Updating the changelog
|
||||
|
||||
After every user-facing change makes it into master, we make a note of it in the
|
||||
changelog, which for historical reasons is kept in `NEWS.md`. The changelog is
|
||||
sorted in reverse order by release version, with the topmost version as the next
|
||||
release (tagged as "(Unreleased)").
|
||||
|
||||
Within each version, there are five available categories you can divide changes
|
||||
into. They are all optional but they should appear in this order:
|
||||
|
||||
1. Backward-compatible changes
|
||||
1. Deprecations
|
||||
1. Bug fixes
|
||||
1. Features
|
||||
1. Improvements
|
||||
|
||||
Within each category section, the changes relevant to that category are listed
|
||||
in chronological order.
|
||||
|
||||
For each change, provide a human-readable description of the change as well as a
|
||||
linked reference to the PR where that change emerged (or the commit ID if no
|
||||
such PR is available). This helps users cross-reference changes if they need to.
|
||||
|
||||
## Documentation
|
||||
|
||||
### Generating documentation
|
||||
|
||||
As mentioned in the Contributing document, we use YARD for documentation. YARD
|
||||
is configured via `.yardopts` to process the Ruby files in `lib/` as well as
|
||||
`NEWS.md` and the Markdown files in `docs/` and write the documentation in HTML
|
||||
form to `doc`. This command will do exactly that:
|
||||
|
||||
```bash
|
||||
bundle exec yard doc
|
||||
```
|
||||
|
||||
However, if you're actively updating the documentation, it's more helpful to
|
||||
launch a process that will watch the aforementioned source files for changes and
|
||||
generate the HTML for you automatically:
|
||||
|
||||
```bash
|
||||
bundle exec rake docs:autogenerate
|
||||
```
|
||||
|
||||
Whichever approach you take, you can view the generated docs locally by running:
|
||||
|
||||
```bash
|
||||
open doc/index.html
|
||||
```
|
||||
|
||||
### About the docsite
|
||||
|
||||
The docfiles that YARD generates are published to the docsite, which is located
|
||||
at:
|
||||
|
||||
<https://matchers.shoulda.io/docs>
|
||||
|
||||
The docsite is hosted on GitHub Pages*. As such, the `gh-pages` branch hosts the
|
||||
code for the docsite. This branch is written to automatically by the
|
||||
`docs:publish` and `docs:publish_latest` tasks.
|
||||
|
||||
The URL above actually links to a bare-bones HTML page which merely serves to
|
||||
automatically redirect the visitor to the docs for the latest published version
|
||||
of the gem. This version is hardcoded in the HTML page, but is also updated
|
||||
automatically by the `docs:publish` and `docs:publish_latest` tasks.
|
||||
|
||||
*\* thoughtbot owns <https://shoulda.io>, and
|
||||
they've got `matchers.shoulda.io` set up on the DNS level as an alias for
|
||||
`thoughtbot.github.io/shoulda-matchers`.*
|
||||
|
||||
## Versioning
|
||||
|
||||
### Naming a new version
|
||||
|
||||
As designated in the README, we follow [SemVer 2.0][semver]. This offers a
|
||||
meaningful baseline for deciding how to name versions. Generally speaking:
|
||||
|
||||
[semver]: https://semver.org/spec/v2.0.0.html
|
||||
|
||||
* We bump the "major" part of the version if we're introducing
|
||||
backward-incompatible changes (e.g. changing the API or core behavior,
|
||||
removing parts of the API, or dropping support for a version of Ruby).
|
||||
* We bump the "minor" part if we're adding a new feature (e.g. adding a new
|
||||
matcher or adding a new qualifier to a matcher).
|
||||
* We bump the "patch" part if we're merely including bugfixes.
|
||||
|
||||
In addition to major, minor, and patch levels, you can also append a
|
||||
suffix to the version for pre-release versions. We usually use this to issue
|
||||
release candidates prior to an actual release. A version number in this case
|
||||
might look like `4.0.0.rc1`.
|
||||
|
||||
### Releasing a new version
|
||||
|
||||
Releasing a new version is very simple:
|
||||
|
||||
1. First, you'll want to be given ownership permissions for the Ruby gem itself.
|
||||
If you want to give someone else these rights, you can use:
|
||||
|
||||
```bash
|
||||
gem owner shoulda-matchers -a <email address>
|
||||
```
|
||||
1. Next, you'll want to update the `VERSION` constant in
|
||||
`lib/shoulda/matchers/version.rb`. This constant is referenced in the gemspec
|
||||
and is used in the Rake tasks to publish the gem on RubyGems as well as
|
||||
generate documentation.
|
||||
1. Finally, you'll want to run:
|
||||
|
||||
```bash
|
||||
rake release
|
||||
```
|
||||
|
||||
This will not only push the gem to RubyGems, but also update the docsite.
|
||||
|
||||
### Re-publishing docs
|
||||
|
||||
In general you'll use the `release` task to update the docsite, but there may be
|
||||
a situation where you'll need to do it manually.
|
||||
|
||||
You can re-publish the docs for the latest version (as governed by
|
||||
`lib/shoulda/matchers/version.rb`) by running:
|
||||
|
||||
```bash
|
||||
bundle exec rake docs:publish_latest
|
||||
```
|
||||
|
||||
This will update the version to which the docsite auto-redirects to the latest
|
||||
version. For instance, if the latest version were 4.0.0, this command would
|
||||
publish the docs at <https://matchers.shoulda.io/docs/v4.0.0> but redirect
|
||||
<https://matchers.shoulda.io/docs> to this location.
|
||||
|
||||
However, if you want to publish the docs for a version and at the same
|
||||
time manually set the auto-redirected version, you can run this instead:
|
||||
|
||||
```bash
|
||||
bundle exec rake docs:publish[version, latest_version]
|
||||
```
|
||||
|
||||
Here, `version` and `latest_version` are both version strings. For instance, you
|
||||
might say:
|
||||
|
||||
```bash
|
||||
bundle exec rake docs:publish[4.0.0, 3.7.2]
|
||||
```
|
||||
|
||||
This would publish the docs for 4.0.0 at
|
||||
<https://matchers.shoulda.io/docs/v4.0.0>, but redirect
|
||||
<https://matchers.shoulda.io/docs> to <https://matchers.shoulda.io/docs/v3.7.2>.
|
||||
|
||||
## Addendum: Labels
|
||||
|
||||
In order to corral the issue and PR backlog, we've found
|
||||
[labels] to be useful for cataloguing and tracking progress purposes. Over time
|
||||
we've added quite a collection of labels. Here's a quick list:
|
||||
|
||||
[labels]: https://github.com/thoughtbot/shoulda-matchers/labels
|
||||
|
||||
### Labels for issues
|
||||
|
||||
* **Issue: Bug**
|
||||
* **Issue: Feature Request**
|
||||
* **Issue: Need to Investigate** -- if we don't know whether a bug is legitimate
|
||||
or not
|
||||
* **Issue: PR Needed** -- perhaps unnecessary, but it does signal to the
|
||||
community that we'd love a PR
|
||||
|
||||
### Labels for PRs
|
||||
|
||||
* **PR: Bugfix**
|
||||
* **PR: Feature**
|
||||
* **PR: Good to Merge** -- most of the time not necessary, but can be helpful in
|
||||
a code freeze before a release to mark PRs that we will include in the next
|
||||
release
|
||||
* **PR: In Progress** -- used to mark PRs that are still being worked on by the
|
||||
PR author
|
||||
* **PR: Needs Documentation**
|
||||
* **PR: Needs Review**
|
||||
* **PR: Needs Tests**
|
||||
* **PR: Needs Updates Before Merge** -- along the same lines as the other
|
||||
"Needs" tags, but more generic
|
||||
|
||||
### Generic labels
|
||||
|
||||
* **Blocked**
|
||||
* **Documentation**
|
||||
* **Needs Decision**
|
||||
* **Needs Revisiting**
|
||||
* **Question**
|
||||
* **Rails X**
|
||||
* **Ruby X.Y**
|
||||
* **UX**
|
61
README.md
61
README.md
|
@ -232,67 +232,6 @@ class PersonTest < ActiveSupport::TestCase
|
|||
end
|
||||
```
|
||||
|
||||
## Running tests
|
||||
|
||||
### Unit tests
|
||||
|
||||
Unit tests are the most common kind of tests in this gem, and the best way to
|
||||
run them is by using [Zeus].
|
||||
|
||||
You'll want to run `zeus start` in one shell, then in another shell, instead of
|
||||
using `rspec` to run tests, you can use `zeus rspec`. So for instance, you might
|
||||
say:
|
||||
|
||||
```
|
||||
zeus rspec spec/unit/shoulda/matchers/active_model/validate_inclusion_of_matcher_spec.rb
|
||||
```
|
||||
|
||||
As a shortcut, you can also drop the initial part of the path and say this
|
||||
instead:
|
||||
|
||||
```
|
||||
zeus rspec active_model/validate_inclusion_of_matcher_spec.rb
|
||||
```
|
||||
|
||||
### Acceptance tests
|
||||
|
||||
The gem uses [Appraisal] to test against multiple versions of Rails and Ruby.
|
||||
This means that if you're trying to run a single test file, you'll need to
|
||||
specify which appraisal to use. For instance, you can't simply say:
|
||||
|
||||
```
|
||||
rspec spec/acceptance/active_model_integration_spec.rb
|
||||
```
|
||||
|
||||
Instead, you need to say
|
||||
|
||||
```
|
||||
bundle exec appraisal 5.1 rspec spec/acceptance/active_model_integration_spec.rb
|
||||
```
|
||||
|
||||
### All tests
|
||||
|
||||
You can run all tests by saying:
|
||||
|
||||
```
|
||||
bundle exec rake
|
||||
```
|
||||
|
||||
## Generating documentation
|
||||
|
||||
YARD is used to generate documentation, which can be viewed [online][rubydocs].
|
||||
You can preview changes you make to the documentation locally by running
|
||||
|
||||
yard doc
|
||||
|
||||
from this directory. Then, open `doc/index.html` in your browser.
|
||||
|
||||
If you want to be able to regenerate the docs as you work without having to run
|
||||
`yard doc` over and over again, keep this command running in a separate terminal
|
||||
session:
|
||||
|
||||
rake docs:autogenerate
|
||||
|
||||
## Contributing
|
||||
|
||||
Shoulda Matchers is open source, and we are grateful for
|
||||
|
|
190
bin/setup
Executable file
190
bin/setup
Executable file
|
@ -0,0 +1,190 @@
|
|||
#!/usr/bin/env bash
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
RUBY_VERSION=$(script/supported_ruby_versions | xargs -n 1 echo | sort -V | tail -n 1)
|
||||
|
||||
cd "$(dirname "$(dirname "$0")")"
|
||||
|
||||
uname=$(uname)
|
||||
|
||||
if [[ $uname == 'Darwin' ]]; then
|
||||
platform='mac'
|
||||
else
|
||||
platform='linux'
|
||||
fi
|
||||
|
||||
banner() {
|
||||
echo -e "\033[34m== $@ ==\033[0m"
|
||||
}
|
||||
|
||||
success() {
|
||||
echo -e "\033[32m$@\033[0m"
|
||||
}
|
||||
|
||||
warning() {
|
||||
echo -e "\033[33m$@\033[0m"
|
||||
}
|
||||
|
||||
error() {
|
||||
echo -e "\033[31m$@\033[0m"
|
||||
}
|
||||
|
||||
has-executable() {
|
||||
type "$1" &>/dev/null
|
||||
}
|
||||
|
||||
is-running() {
|
||||
pgrep "$1" >/dev/null
|
||||
}
|
||||
|
||||
install() {
|
||||
local apt_package=""
|
||||
local rpm_package=""
|
||||
local brew_package=""
|
||||
local default_package=""
|
||||
local package=""
|
||||
|
||||
for arg in "$@"; do
|
||||
case $arg in
|
||||
apt=*)
|
||||
apt_package="$arg"
|
||||
;;
|
||||
rpm=*)
|
||||
rpm_package="$arg"
|
||||
;;
|
||||
brew=*)
|
||||
brew_package="$arg"
|
||||
;;
|
||||
*)
|
||||
default_package="$arg"
|
||||
;;
|
||||
esac
|
||||
done
|
||||
|
||||
if has-executable brew; then
|
||||
package="${brew_package:-$default_package}"
|
||||
|
||||
if [[ -n $package ]]; then
|
||||
brew install "$package"
|
||||
fi
|
||||
elif has-executable apt-get; then
|
||||
package="${apt_package:-$default_package}"
|
||||
|
||||
if [[ -n $package ]]; then
|
||||
sudo apt-get install -y "$package"
|
||||
fi
|
||||
elif has-executable yum; then
|
||||
package="${yum_package:-$default_package}"
|
||||
|
||||
if [[ -n $package ]]; then
|
||||
sudo yum install -y "$package"
|
||||
fi
|
||||
else
|
||||
error "Sorry, I'm not sure how to install $default_package."
|
||||
exit 1
|
||||
fi
|
||||
}
|
||||
|
||||
check-for-build-tools() {
|
||||
if [[ $platform == "linux" ]]; then
|
||||
if ! has-executable apt-get; then
|
||||
error "You don't seem to have a package manager installed."
|
||||
echo "The setup script assumes you're using Debian or a Debian-derived flavor of Linux"
|
||||
echo "(i.e. something with Apt). If this is not the case, then we would gladly take a"
|
||||
echo "PR fixing this!"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# TODO: Check if build-essential is installed on Debian?
|
||||
else
|
||||
if ! has-executable brew; then
|
||||
error "You don't seem to have Homebrew installed."
|
||||
echo
|
||||
echo "Follow the instructions here to do this:"
|
||||
echo
|
||||
echo "http://brew.sh"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# TODO: Check that OS X Command Line Tools are installed?
|
||||
fi
|
||||
}
|
||||
|
||||
install-development-libraries() {
|
||||
install apt=ruby-dev rpm=ruby-devel
|
||||
install rpm=zlib-devel
|
||||
}
|
||||
|
||||
install-dependencies() {
|
||||
if ! has-executable sqlite3; then
|
||||
banner 'Installing SQLite 3'
|
||||
install sqlite3
|
||||
install apt=libsqlite3-dev rpm=sqlite-devel
|
||||
fi
|
||||
|
||||
if ! has-executable psql; then
|
||||
banner 'Installing PostgreSQL'
|
||||
install postgresql
|
||||
install apt=libpq-dev rpm=postgresql-devel
|
||||
fi
|
||||
|
||||
if ! is-running postgres; then
|
||||
banner 'Starting PostgreSQL'
|
||||
start postgresql
|
||||
fi
|
||||
|
||||
if ! has-executable heroku; then
|
||||
banner 'Installing Heroku'
|
||||
install heroku/brew/heroku heroku
|
||||
fi
|
||||
|
||||
if has-executable rbenv; then
|
||||
if ! (rbenv versions | grep $RUBY_VERSION'\>' &>/dev/null); then
|
||||
banner "Installing Ruby $RUBY_VERSION with rbenv"
|
||||
rbenv install --skip-existing "$RUBY_VERSION"
|
||||
fi
|
||||
elif has-executable rvm; then
|
||||
if ! (rvm ls | grep $RUBY_VERSION'\>' &>/dev/null); then
|
||||
banner "Installing Ruby $RUBY_VERSION with rvm"
|
||||
error "You don't seem to have Ruby $RUBY_VERSION installed."
|
||||
echo
|
||||
echo "Use RVM to do so, and then re-run this command."
|
||||
echo
|
||||
fi
|
||||
else
|
||||
error "You don't seem to have a Ruby manager installed."
|
||||
echo
|
||||
echo 'We recommend using rbenv. You can find installation instructions here:'
|
||||
echo
|
||||
echo 'http://github.com/rbenv/rbenv'
|
||||
echo
|
||||
echo "When you're done, simply re-run this script!"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
banner 'Installing Ruby dependencies'
|
||||
gem install bundler --conservative
|
||||
bundle check || bundle install
|
||||
bundle exec appraisal install
|
||||
|
||||
if ! has-executable node; then
|
||||
banner 'Installing Node'
|
||||
|
||||
if [[ $platform == 'linux' ]]; then
|
||||
curl -sL https://deb.nodesource.com/setup_10.x | sudo -E bash -
|
||||
|
||||
install nodejs
|
||||
|
||||
if ! has-executable npm; then
|
||||
install npm
|
||||
fi
|
||||
else
|
||||
install nodejs
|
||||
fi
|
||||
fi
|
||||
}
|
||||
|
||||
check-for-build-tools
|
||||
install-development-libraries
|
||||
install-dependencies
|
Loading…
Reference in a new issue