Using Hudson as Rails CI server 1

Posted by david

For some time, Hudson has become my favorite continuous integration server. It's easy to configure and provides a handful of really interesting plug-ins. The only thing that I missed was the possibility of use Rake as a project build tool and thus I'll be able to take my java, ruby or rails projects into the same CI server.

Well, past weekend I had too much spare time so I decided to develop my first Hudson plugin and this morning I've released the first version of the Hudson Rake plugin.

Once you have installed Hudson you just need to donwload the plug-in and upload it from the Manage Hudson section:

When the plugin is avalable it detects your ruby instances installed from your PATH but it allows you to add other ruby or jruby paths:

Finally you just need to select the Invoke Rake option into the project configuration and select the tasks that you want to Hudson executes:

That's it, you are ready to go with Rake, Hudson and the Continuous Integration Game.

Usa ruby para testear tu código java 2

Posted by david

Aunque navegando por la web se pueden encontrar artículos sobre cómo usar rspec para testear código java y ya existe algún framework de bdd para java, desde hace unas semanas existe una librería que nos da las mejores herramentas de test que ruby posee para aplicarlas con nuestro código java.

JtestR es una librería que integra jruby con rspec, dust, mocha y ActiveSuport, y permite ejecutar nuestros test escritos en ruby con herramentas de automatización como Ant o Maven.

Para ejecutarlos con Ant es tan facil como incluir una nueva tarea en nuestro fichero de configuración:

<target name="test" description="Runs all tests">
  <taskdef name="jtestr" classname="org.jtestr.ant.JtestRAntRunner" classpath="lib/jtestr.jar"/>

  <jtestr tests="test/ruby"/>
</target>

Pero lo que más me gusta de este framework es poder usar rspec para testear mis clases java, un sencillo ejemplo podría ser este:

import java.util.HashMap

describe HashMap, "is empty" do
  before :each do
    @map = mock(HashMap)
  end

  it "should be empty" do
    @map.stubs(:size).returns(0)

    @map.should be_empty
  end
end

Una herramienta a tener en cuenta si, como yo, pasas el día entre código java y código ruby :-).

BDD & RSpec rulez 0

Posted by david

¿Por qué deberías pensar en usar BDD y RSpec?

Un ejemplo vale más que mil palabras

AtomPub, ruby y la api de 11870.com 2

Posted by david

Así se titula la charla que imparto en la segunda conferencia rails. Pretende ser una introducción a atomPub, la api de 11870 y todo esto mezclado con un poco de ruby.

Ya podéis descargar la presentación en formato pdf. Agradezco cualquier comentario, espero que sea útil.

Actualización: he subido la presentación a SlideShare para que se pueda ver desde aquí.

Conferencia Rails 2007 0

Posted by david

Este jueves comienza la segunda Conferencia Rails Hispana. Este año estaré hablando sobre AtomPub, ruby y la api de 11870.com. Cuando acabe subiré la presentación aqui para uso y disfrute.

ponente

Nos vemos allí.

Rails plugin: atom_pub_server 0

Posted by david

Coincidiendo con el lanzamiento de la api de 11870.com tenía ganas de liberar un plugin para Rails que me ha ayudado a experimentar con AtomPub.

Como no soy muy original con los nombres lo he llamado atom_pub_server y básicamente sirve para empezar a implementar AtomPub dentro de una aplicación desarrollada con Rails. Ya que el punto de entrada del protocolo es su documento de servicio este plugin sirve para generar un documento de servicio a partir de los controllers de una aplicación. A partir de ahí, y gracias al genial soporte de REST por parte de rails y a alguna de las novedades de la versión 2.0 implementar un servidor de Atom Publishing Protocol con una aplicación rails es francamente sencillo.

Pero para ver como funciona el plugin lo mejor es ver un ejemplo. Empezaremos instalándolo en la aplicación desde el repositorio:

    $script/plugin install http://svn.thinkincode.net/rails/plugins/atom_pub_server

Supongamos que nuestra aplicación tiene dos controllers, uno llamado PostsController y otro llamado ServicesController. El primero será en encargado de gestionar una colección de recursos, así que le añadiremos el siguiente método:

    class PostsController < ApplicationController
      acts_as_collection :title => 'posts', :workspace => 'blog',
        :href=> 'http://myblog', :accept => Mime::ATOM_ENTRY
    ...

Al marcar este primer controlador para que actúe como una colección automáticamente se le añade un filtro anterior a los métodos de crear y actualizar un elemento. El método que invoca el filtro se debe llamar filter_content_type y los nombres de los métodos sobre los que se ejecuta se pueden configurar como variables de entorno, siendo por defecto create y update.

El segundo controlador será el encargado de generar el documento de servicio, así que lo marcaremos como tal:

    class ServicesController < ApplicationController
        acts_as_service_document
    ...

Finalmente, para que el controlador genere el documento de servicio solo tendremos que llamar al método "service_document" que le aporta el plugin dentro de otro de los métodos del controlador:

    def index
      render :xml => service_document
    end

y nos generará un xml parecido a este:

  <service xmlns:atom='http://www.w3.org/2005/Atom' xmlns='http://www.w3.org/2007/app'>
    <workspace>
      <atom:title>blog</atom:title>
      <collection href='http://myblog'>
          <atom:title>posts</atom:title>
          <accept>application/atom+xml;type=entry</accept>
     </collection>
    </workspace>
  </service>

Además, este plugin añade varios tipos Mime necesarios para la cumplir especificación de AtomPub:

    Mime::ATOM_ENTRY == 'application/atom+xml;type=entry'
    Mime::ATOM_SVC == 'application/atomsvc+xml'
    Mime::ATOM_CAT == 'application/atomcat+xml'

Para finalizar, he decidido sobreescribir uno de los nuevos helpers de rails, concretamente el que nos ayuda a escribir documentos Atom. El método original no permite añadir nuevos espacios de nombres siendo su llamada tal que así:

    atom_feed do |feed|
    ...

mientras que con este plugin podríamos escribir:

    atom_feed( 'xmlns:app' => 'http://www.w3.org/2007/app') do |feed|
    ...

Cabe decir que el método para sobreescribir 'atom_feed' sólo funciona con la versión actual de Rails (2.0RC) y posteriores. En el fichero README del plugin se puede encontrar una documentación mucho más detallada. Cualquier duda, sugerencia o mejora es bienvenida.

Validando feeds contra el w3c 0

Posted by david

Ultimamente he pasado demasiado tiempo jugando con los feeds de 11870, pero aunque tengo el proceso de creación bastante trillado y lo he dejado muy DRY nunca está de más validarlos.

El w3c tiene una web que te permite validar un feed alojado en una determinada url o pastearle el código que este genera dentro den un textarea. La principal pega es que si tu url es la de tu ordenador de desarrollo no la acepta y tienes que optar por la segunda opción.

Por suerte se les ocurrió liberar un api para no tener que estar copiando y pegando cada vez que queramos validar un feed que estemos desarrollando. Con esta api me he creado un script que indicándole el host y la ruta del feed, lo descarga y lo intenta validar contra el w3c, no es nada del otro mundo y seguro que es muy mejorable pero a mi me ha sido bastante útil.

Básicamente se trata de recoger el xml que genera el feed con la siguiente instrucción:

@response = Net::HTTP.get_response ARGV[0], ARGV[1], 80

Y enviarlo al validador:

v = W3C::FeedValidator.new
v.validate_data @response.body.to_s 

Una vez hecho esto podremos comprobar si el feed es válido con el método valid? y acceder a los mensajes a través de las variables errors, warnings e informations.

NOTA: El validador del w3c no funciona muy bien y de vez en cuando da algún error al validar, solo hay que insistir un poco hasta que pilla vuestro feed ;)

Crear fixtures fácilmente 2

Posted by david

Ruby on rails nos proporciona muchas comodidades a la hora de hacer desarrollos orientados a test. Quizá uno de los mayores inconvenientes sea tener que escribir nuestas fixtures, porque al trabajar con modelos algo complicados puede que no sean todo lo válidas que nos gustaría.

Fixturease es una gema que nos permite crear fixtures directamente a partir del modelo de nuestra aplicación.

Su instalación es muy sencilla:

sudo gem install fixturease

Una vez instalada, nos situamos en el directorio raiz de nuesta aplicación y ejecutamos el script fixturease.rb. Este, nos abrirá una consola que nos permitirá crear nuestas fixtures.

Supongamos que ejecutamos en esta consola el siguiente comando:

@david = User.create(:login => 'david', :password => 'pass')

Fixturease nos creará el fichero fixtures/users.yml con la siguiente entrada:

david:
  id: 1
  password: pass
  login: david
  created_at: 2007-01-20 21:40:23.250000 +02:00

Creo que es una buena forma de tener un poco más de control sobre nuestas fixtures y no tener que centrarnos en escribir un fichero yaml a mano.