-
Notifications
You must be signed in to change notification settings - Fork 24
Developing
So you want to write code in Umlaut gem itself.
First, note that you may not have to for localization. The most common thing you'd want to do is add a new Service Plugin. You can add a new service plugin solely in your local app, and reference it in your umlaut_services.yml. However, if it's possibly useful to someone else, it would be great if you contributed it back to Umlaut, and that would require editing Umlaut source.
Or you may just want to explore the source and maybe even edit it experimentally, that's cool.
(Please note: You can edit Umlaut code to contribute a patch back to Umlaut, or experimentally. But you should not need to run your application live against locally edited Umlaut source code. If you do so, you have locally forked Umlaut, and it will make upgrading to future versions of Umlaut difficult. It should be possible to make any local changes you need with local configuration or over-rides located in your local app. If there's something that needs to be easier... well, that's indeed a reason to fix Umlaut to make it easier and contribute your fix back to Umlaut!)
So ordinarily when you install Umlaut into a local app, the actual Umlaut source is off in your system (or rvm, etc) gem repository, which is not a place you'd want to edit it.
You can use git to check out a copy of Umlaut source wherever you want from your github repo. But Umlaut's a gem, you can't actually run it to test it. How do you run an application against an arbitrary local umlaut version in your file system?
Two ways:
-
In any arbitrary umlaut-using local app, you can simply point it to a local checkout of Umlaut in the app's Gemfile, using the :path option. Relative paths are fine.
gem 'umlaut', :path => '../umlaut'
You wouldn't want to actually deploy or run an app in production like this, it's best to deploy against actual released versions of Umlaut. But for testing and experimentation and development.
-
The umlaut source comes with a very basic dummy app in
./test/dummy
. There's no database.yml though. Create one, pointing to a local mysql database, runrake db:migrate
, and you can just start the dummy app running against the checkout of umlaut in the directory that contains it. Edit the./config/umlaut_services.yml
if you want, etc.This dummy app was actually created by the
rails plugin new
generator for purpose of running automated tests against, see below.
Note: Until we cut over, Umlaut 3.x is in the github repo in umlaut3dev
branch, master is still umlaut 2.x at the moment.
See also Writing a Service Plugin
Sorry, Umlaut doesn't contain much in the way of automated testing, and what is there may or may not be passing. This is unfortunate, we know.
This situation comes about through a combination of: Umlaut's long history, including beginnings with no tests and many major architectural (such as through Rails versions since 1.x!) that broke the tests that were there; general developer laziness; and some genuine difficulty in figuring out how to easily test something like Umlaut that relies on so many localized external services (Umlaut doesn't do much at all by itself, it just calls out to various things that are local or require private API keys).
Nevertheless, we'd love to have some better test coverage. So we can't say that tests are really required for commits, but they're definitely a good idea.
We used rails 3.1 rails plugin new
generator to create a gem plugin skeleton for Umlaut. One thing this did was create a ./test/dummy
dummy app in umlaut source. This is meant for running tests against. Tests you write in /test/*
will run against the dummy app. The dummy app can have configuration customized (with those changes committed) if needed to exersize certain features (although changing config 'live' and temporarily in a test itself would be preferable where feasible).
The dummy app doesn't have a database.yml
, you'll need to add one pointing at a local mysql (not sqlite3, umlaut won't work against sqlite3).
Please use straight Test::Unit and/or Minitest. Please do not use rspec, cucumber, etc. Put tests in ./test
. There's already a rake test
to run all tests.
Tests should pass for everyone with a straight umlaut checkout without modifying any files but adding a database.yml.
Please don't add tests that raise or fail without a private API key or access to a private server. Exactly how to do this is unclear. The VCR gem may come in handy, but we haven't tried it much yet -- potentially, you could use VCR to record HTTP responses run against private/authenticated services, but then store them in the dummy app (commit to repo), so other people can run tests against those 'mock' responses. We'd want to figure out a way for someone with access to the neccesary third party platforms to choose to run against 'live' too (for only specified services?) (and then commit the new versions of the responses back to repo if they want). There's some stuff to figure out, yeah.
If you really must write tests that require private api keys or access to private servers to pass, then I guess that's better than no tests at all, but figure out a way to:
- clearly document where the developer should put those private api keys or local server URLs to get tests to pass.
- Keep from interfering with running the rest of the test suite for a developer who does not have that private information filled out. Ideally tests that require it would output a clear 'skipped' or 'pending' message (explaining what needs to be configured to run them_ rather than failing. In no cases should they raise exceptions in such a way that prevents the rest of the test suite from continuing.
Umlaut comes with a bunch of service plugins included.
You/we could instead release one or more service plugins as seperate gems, that depend on Umlaut. A user would need to install the umlaut_crazy_service gem, and then they'd have access to service plugin same as anything else. No special magic, the seperate gem just needs to depend on umlaut in it's gemspec, and include a class defining a service per Umlaut conventions.
Why might you want to do this?
- The service has a lot of dependencies that we don't want core umlaut to need to depend on
- You want to be able to release updates to the service plugin on it's own release schedule, not tied to updates of umlaut.
- You want to control the service yourself and do whatever you want with it, not subject to other umlaut developers ideas. Or you want/need to release it under a different license.
What are the downsides?
- A bit more apparatus to work with as a developer, a bit more confusing as a developer (not so much as a user), a bit more work to make sure the independent gem keeps working with Umlaut as umlaut evolves, keep track of what versions of Umlaut your independent gem works with, etc.
So you're not an Umlaut committer, but you'd like to submit a change back to Umlaut.
-
Fork in github, create a new "feature" branch in your forked github, and commit your changes there.
-
Then submit a github pull request back to Umlaut. See also http://www.mikeball.us/blog/how-to-contribute-to-a-project-hosted-on-github
-
Small single purpose pull requests are better than massive conglomerations. If you need massive changes, try to break them into steps and submit pull requests for smaller changes at a time.
-
Please feel free to ask for feedback on the umlaut listserv on your general approach before embarking on a massive change, to make sure you're working in a direction likely to be accepted.
Once you've contributed a quality change or two to Umlaut, odds are we'll make you a committer.
Generally only done by project lead or what have you. Needs to have permissions set on rubygems for the umlaut
gem.
We use the bundler-supplied rake tasks for releasing the gem. Update ./lib/umlaut/version.rb
to desired version.
Then simply run: rake release
This will create a tag with version in umlaut git repo, as well as release the new version to rubygems.org.