h2o is open-source software designed to replace bulky and expensive law textbooks with an easy-to-use web interface where instructors and students alike can author, organize, view and print public-domain course material.
- Live version
- Development: manual setup
- Development: using Docker
- Testing
- Migration
- Contributions
- License
TODO: These instructions are incomplete for dev platforms other than OS X, and probably lack steps needed on a fresh machine.
- Install RVM (if missing) with
\curl -sSL https://get.rvm.io | bash -s stable --auto-dotfiles
, thensource ~/.bash_profile
etc. - Install the project Ruby version (e.g.
rvm install $(<.ruby-version)
) cd
into the h2o directory (orcd .
if already there) to create the gemset.
gem install bundler && bundle install
- (If Bundler complains about missing library dependencies, install them and
bundle install
until it succeeds.)
- Installation of yarn is platform-specific. On a Mac: if you already have node installed,
brew install yarn --without-node
, orbrew install yarn
to simultaneously install node. yarn install
Heads up: yarn install
might get re-run for you behind the scenes under a number of circumstances. For instance,
- Guard is configured to re-run yarn install when package.json changes
- Rails includes a
yarn:install
task that may be called from other Rails/Rake tasks, includingassets:precompile
- Webpacker also runs
yarn:install
under certain circumstances
We disabled some of the magic to give us more control. You might want to keep an eye on your console, in case you are expecting yarn install
to run automatically some place we've disabled it, or in case it runs some time when you aren't expecting it!
- Install postgres ~9.6 (if missing). Note:
brew install postgres
now installs postgres 10+. To install 9.6.5 via Homebrew, install postgres using the specific version formula (brew install https://raw.githubusercontent.com/Homebrew/homebrew-core/d014fa223f77bee4b4097c5e80faa0954e28182f/Formula/postgresql.rb
) and then runbrew switch postgres 9.6.5
- Start solr with
rails sunspot:solr:start
- Create and initialize the database with
rake db:setup
(orrake db:reset
) - Stop solr with
rails sunspot:solr:stop
Note: If rake db:setup
fails with a message like Sunspot::Solr::Server::NotRunningError
, try
rails sunspot:solr:run
to see why solr failed to start. You may need to update your java installation
with brew cask install java
- Copy
.env.example
to.env
- Replace the values in
.env
with your own environment variables
- Run
guard
. It will take several seconds to: - Make sure the bundle is up-to-date;
- Start the dev/test Solr server;
- Load Spring for fast
rails
/rake
commands; - And finally boot Rails.
- (Optionally, install a notifier such as Growl or
brew install terminal-notifier
for Guard notifications.) - Guard will now be watching the project for changes and will restart Spring/Rails when needed. This can also be done from the guard command line, e.g.
reload rails
. - When finished, type
exit
to shut everything down and close Guard.
- e.g. OS X:
echo 127.0.0.1 h2o-dev.local | sudo tee -a /etc/hosts
- Go to http://h2o-dev.local:8000
To ensure that URLs resolve correctly, add the following domain to your computer's hosts file:
127.0.0.1 h2o-dev.local
For additional information on modifying your hosts file, try this help doc.
Start up the Docker containers in the background:
$ docker-compose up -d
The first time this runs, it will build the 2.33GB Docker image, which may take several minutes. (After the first time, it should only take 1-3 seconds.)
Finally, initialize an empty database...
$ bash docker/init.sh
...or a database seeded with data from a pg_dump file:
$ bash docker/init.sh -f ~/database.dump
You should now have a working installation of H2O!
Spin up the development server:
$ bash docker/run.sh
Or, run the tests:
$ bash docker/test.sh
When you are finished, spin down Docker containers by running:
$ docker-compose down
Your database and solr index will persist and will load automatically the next time you run docker-compose up -d
.
Or, you can clean up everything Docker-related, so you can start fresh, as with a new installation:
$ bash docker/clean.sh
Since we're going to be heavily refactoring and likely removing a lot of code, the focus for now will be on high-level feature tests which will survive that. cases_test.rb is an example of the test pattern using Minitest and Capybara which exercises the full stack from a user's point of view.
Rails test scenarios marked with js: true
will be run in a headless WebKit
environment via Poltergeist. This requires the chromedriver binary to
be installed, e.g. brew cask install chromedriver
. Headless tests
are significantly slower than static tests, so prefer to avoid writing
Rails tests (and features!) that require JS when possible.
ImageMagick and a global installation of the "Garamond" font are required. On Macs, you can verify the presence of Garamond in Applications > FontBook, and can install ImageMagick via brew install imagemagick
.
yarn test
runs javascript tests using Mochabin/rails test
runs non-system Rails tests.bin/rails test:system
runs system Rails tests, including tests requiring JS.bin/rails test test/system/cases_test.rb
runs the case feature test, and so on.
Coverage will be generated automatically for all manually-run tests.
TODO: When coverage is a bit higher, add a git commit hook which runs the coverage report and fails if under some value.
Legacy Playlists must be converted into Casebooks. To convert all un-migrated, use this rake task:
bin/rails h2o:migrate_playlists
Any Playlists that don't have a Casebook with a matching created_at
date will be migrated.
You can also migrate individual playlists from the rails console:
bin/rails c
> Migrate::Playlist.find(52410).migrate
=> #<Content::Casebook ... >
> Migrate::Playlist.find([11494, 5456, 1496]).map &:migrate
=> [#<Content::Casebook id: ...>, ...]
If importing data from another installation of H2O into your local database, you may need to create an h2oadmin role in postgres first (e.g., psql postgres
, followed by CREATE ROLE h2oadmin;
. Note the terminating semi-colon).
Be advised that depending on the source of the data, some local rake tasks (e.g. db:reset
) may subsequently fail with spurious warnings about affecting production data, regardless of the current value of RAILS_ENV
.
Contributions to this project should be made in individual forks and then merged by pull request. Here's an outline:
- Fork and clone the project.
- Make a branch for your feature:
git branch feature-1
- Commit your changes with
git add
andgit commit
. (git diff --staged
is handy here!) - Push your branch to your fork:
git push origin feature-1
- Submit a pull request to the upstream master through GitHub.
Whenever possible, pull requests should be fast-forwarded (i.e., Rebase and Merge
d). This creates a nice, linear record of commits, without ugly merge commits that lose context and history.
In order to fast-forward a pull request, upstream/master
shouldn't have any commits that aren't also on the fork in the same order— in other words, they have to agree about the history of the repo. This is a problem if upstream has changed since you created your branch!
Rather than creating a merge commit which reconciles the changes, you'll want to rebase
your branch to upstream/master
. Rebasing simply means that you stash your new commits temporarily, fast-forward your local repo to the updated upstream/master
, and then apply your changes on top, pretending that your commits are the most recent changes.
In general, GitHub can automatically rebase a pull request, but if there are any conflicts you'll need to resolve them manually with this process:
- Add the upstream repository with
git remote add upstream
- Fetch the latest changes with
git fetch upstream
- Rebase your branch to upstream:
git rebase upstream/master
- (You can do both of these in one step with
git pull upstream master --rebase
) - If
upstream/master
has changes that conflict with your commits, you'll need to amend them at this time. - Push and pull request.
In the case of particularly ugly conflicts, rebasing can be more trouble than it's worth to preserve history, and a big merge commit will be the best option, but that should be avoided whenever possible. Rebasing your local branch to upstream/master
frequently is the best way to avoid headaches later on.
This codebase is Copyright 2017 The President and Fellows of Harvard College and is licensed under the open-source AGPLv3 for public use and modification. See LICENSE for details.