|
DevelopmentEnvironment
XPrest Development Environment
IntroductionThis page describes the development environment at the time development started; January, 2009. It is not succinct, for an always up-to-date listing of the tools in use, you may visit XprestTooling. EnvironmentDevelopment PlatformThe Xprest project will be developed in Ruby on Rails. Rails is chosen because:
It's likely that in typical short-sighted enterprise fashion that Rails (and similar) is not on the approved list for development or deployment. If this is true for you, then, I'm genuinely sorry. However, if your restriction is really on the deployment end, where everything has to run in, say, WebSphere, then I highly recommend JRuby and Warble. Together, these tools allow you to take a Rails application (runtime, gems, and all) and package it as a war file to drop in any servlet container. Really, who's gonna know? Deployment PlatformThe deployment platform is also Rails, while in development mode we'll stick with the default WEBrick Web server. Describing how to deploy a Rails app is out of scope for this tutorial. However, there are a lot more options than there used to be. DatabaseWe'll be using PostgreSQL 8.3. We're not going to use the built in SQLite for two reasons: 1. I can foresee a time in this project we're it's important to have a distinct database process and 2. Postgres more closely resembles the RDBMSs typically found in an enterprise setting, e.g. Oracle and DB2. I've also decided against the previous default of MySQL because, well, ick. That said, I don't anticipate doing anything much outside of ActiveRecord or that's Postgres specific, so if you wanna play along at home with a different database, then go for it. Operating SystemI'll be using Ubuntu. You can use whatever you want. I don't anticipate that any part of Xprest will be operating specific, but all command line examples will assume Ubuntu. You may or may not need to translate to other nix variants. I will make no attempt to make sure Xprest runs on Windows. Gems and pluginsXprest will undoubtedly use a number of Gems and/or plugins. However, at this point I know I'll be using at least two: Haml and RSpec/Spec::Rails. TestingFor testing purposes we will go outside the Rails defaults and use RSpec and Spec::Rails. Why? Mainly because these are what we use in my day job. But also because I want to give Cucumber a shot (previously we tried and failed to use StoryRunner properly). Continuous IntegrationXprest will use Hudson for continuous integration. The Hudson instance can be found here. It's locked down so that only I can configure it and trigger builds, but anyone can view the results over time. Browser SupportFirefox 2 & 3 and, because we're coding for the enterprise, IE7. I will not attempt to support IE6 even though this is (unbelievably) still the default on many enterprise desktops. InstallationIf you plan to follow along at home or even extend Xprest to be truly viable and then install it your enterprise, here are some rough instructions to get you started. Some of these packages were already installed on my dev system, so your mileage may vary. If these instructions are off a little, then just do what Google tells you to do. It should all be pretty simple. Installing RubyI'll be using the standard Ruby interpreter (MRI), everything should work just fine, if not better, in JRuby. Ruby is not 'pre-installed' on Ubuntu, so if you don't already have it, install it as follows. Remember, installation instructions are for Ubuntu (8.04, Hardy Heron) only. $ sudo apt-get install ruby irb rdoc $ sudo apt-get install ruby1.8-dev Net::HTTPS is not included by default in the Ruby packages, since this is a requirement for Rails, you must install it as follows: $ sudo apt-get install libopenssl-ruby Installing RubyGemsYou'll need RubyGems installed if you haven't got it already. Lets do that now. My experience and others is that the Ubuntu package for RubyGems is unworkable, so you'll want to build this one yourself. Fortunately, it's very simple. First, download RubyGems the latest version of RubyGems from RubyForge. At the time of this writing RubyGems is at 1.3.1 Then build it: $ wget http://rubyforge.org/frs/download.php/45905/rubygems-1.3.1.tgz $ tar -zxvf rubygems-1.3.1.tgz $ cd rubygems $ sudo ruby setup.rb [optional] $ sudo ln -s /usr/bin/gem1.8 /usr/bin/gem Ruby on RailsNote: With the exception of RSpec it is not strictly necessary for anyone but me to do these next few steps. I'll be bundling Rails and all required gems and plugins into the SVN repository. You will, if you want to run and test Xprest locally, need to install RSpec/Spec::Rails as described below. Question for readers: Is it a good practice to include Rails and other Gems in your repository, or should I be using svn:externals or some other technique? Because this project is extremely low risk, I'll be using Edge Rails so as to get all that 2.3 goodness. I have no idea how stable HEAD is, but that's what I'm gonna grab. If there are obvious bugs, I'll go up and down revisions as needed. There are a number of ways to get Edge Rails, but what I'm going to do is simply grab the latest released version of Rails, then use the Rake tasks to grab and freeze edge. $ sudo gem install rails If this generates a connect error, try: $ sudo gem install rails -p Since we are going to freeze Edge into our application (that is, grab the latest trunk version and install it with our application's directory structure), we're first going to need an application. $ rails xprest That will have created the structure for a default Rails application in whatever directory you executed it from. Now lets get Edgy (that's Rails edgy, by the way, not Ubuntu Edgy). $ cd xprest $ rake rails:freeze:edge That worked, but running ./script/about blew up with: Could not find RubyGem rack (>= 0.9.0) (RuntimeError) Apparently Edge has a dependency on Rack (the Ruby equivalent of the Java Servlet specification, i.e., the one true way to interface between a Web server and a Ruby-based Web application). Lets get it now. $ sudo gem install rack Lets see how things look now. $ ./script/about About your application's environment Ruby version 1.8.6 (i486-linux) RubyGems version 1.3.1 Rails version 2.3.0 Active Record version 2.3.0 Action Pack version 2.3.0 Active Resource version 2.3.0 Action Mailer version 2.3.0 Active Support version 2.3.0 Edge Rails revision unknown Application root /home/placey/xprest Environment development Database adapter sqlite3 Perfect. Next, just like we want to bundle Rails up with our application, we'll want to also bundle up all (or as many as possible) of its dependencies. That is, we want to put the Rack Gem under Rails as well. Thankfully, it's a Rake task away. First tell Rails what Gems you're dependent on by adding this to the config/environment.rb file (you'll see where): config.gem "rack" Then run: $ rake gems:unpack The above puts the Gem in the vendor/gems directory (in my case after generating an unimportant warning). HamlWe'll be using Haml for all of our views because, well, ERB is ugly and Haml is beautiful. We'll install it the same manner as Rack. Add the following to config/environment.rb: config.gem "haml" Then download the gem and unpack it into the vendor directory: $ sudo rake gems:install $ rake gems:unpack RSpecNext we'll go get RSpec and Spec::Rails, our test framework. As of RSpec 1.1.5, it too is now a Gem. Because Xprest is not strictly dependent on RSpec and we don't want it loaded in all environments all the time we will not add it to our environment. Simply install it the old fashioned way. Note, installing Spec::Rails will install RSpec too. gem install rspec-rails PostgreSQLAs discussed earlier, we'll be using PostgreSQL for our application. If you don't already have it, install it now. sudo apt-get install postgresql postgresql-client Now we need to add a user for our application to connect to Postgres as. So, first become root, then become the postgres user, then create an Xprest user and make that user a Postgres superuser. This is okay for development purposes, for production we will ultimately create a less powerful user for Rails to connect as. In order to avoid having to become root all the time, you may want to create another Postgres user with the same name as your OS user. $ su # su postgres $ createuser -P xprest (Say 'yes' to the superuser question. Give any password you want, but remember it.) $ createuser placey (or whatever your Linux/Unix login name is. No password this time.) $ exit # exit Next we need to get the Rails-Postgres database adapter. It's a little confusing right now as to what to grab. However, the ruby-pg Gem seems to be current and mandated by EdgeRails. This Gem compiles and links locally, so you'll need a build environemnt and the Postgres header files to make it succeed. $ sudo apt-get install build-essential $ sudo apt-get install libpq-dev $ sudo gem install pg Now, lets tell Rails what it needs to know to connect to Postgres. Edit config/database.yml to look (more or less) as follows: development: adapter: postgresql database: xprest_development username: xprest password: <your password> host: localhost pool: 5 timeout: 5000 # Warning: The database defined as "test" will be erased and # re-generated from your development database when you run "rake". # Do not set this db to the same as development or production. test: adapter: postgresql database: xprest_test username: xprest password: <your password> host: localhost pool: 5 timeout: 5000 production: adapter: postgresql database: xprest_production username: xprest password: <your password> host: localhost pool: 5 timeout: 5000 If everything went according to plan you should be able to run rake db:create and connect to the development database. $ rake db:create $ psql xprest_development Removing TemptationNote: You don't need to do this either, you'll get it if you grab the source from the SVN repo. The last thing we want to do is to remove some of those Rails defaults that make may lead us into non-RESTful temptation. First, recognize that Rails has what amounts to two distinct routing systems, one RESTful one not so RESTful, and the default is to automatically do the 'right thing' for non-RESTful routes. So lets comment out that default lest we accidentally or lazily start going down the wrong path. To do that, comment out the last two lines of config/routes. # map.connect ':controller/:action/:id' # map.connect ':controller/:action/:id.:format' It's important to note that the default Rails routes are not un-RESTful, they are simply less RESTful than ideal. Indeed all URLs are RESTful. Similarly, we'll want to, at least for now, remove support for sessions. Because sessions, as we know, are the root of all evil. Add the following to the core ApplicationController in the app/controllers directory. # It's too easy to misuse sessions and end up with brittle systems that are hard # to scale. Uncomment only as necessary and limit the use of sessions as much as # possible http://api.rubyonrails.org/classes/ActionController/SessionManagement/ClassMethods session :off And because we're not using sessions we don't have to worry about using Rails's support for cross-site request forgery, which we can leave comment out. Checking in / Checking outThat's it, for now. There will most likely be more Gems and more configuration changes. But we have enough to make our first commit and move on to the addressing our user's stories. $ svn add * $ svn commit -m "Initial commit of a default Rails app configured for Postgres and RESTful support." Currently only I can commit to this repository (I hope to change this once this project matures), but if you want to review the code locally, build it, and alter it, you can check it out as follows: $ svn checkout http://xprest.googlecode.com/svn/trunk/ xprest-read-only |
I'm a little unsure about your choice of Haml, but I understand why you're chosing it. (My main reason for not using it is that we often work with web designers, who very easily can edit .erb files, but not Haml). I'll follow along using sqlite, if possible I think it would be cool for the project to work with it too (unless it becomes too costly).
And you can't (and don't need to) turn sessions off anymore in Rails 2.3 (they're created lazily when needed, just be sure to remove the flash-using bits from the scaffolded controllers).