Oferta laboral

May 7th, 2008

Hace un tiempo no era sencillo encontrar este tipo de ofertas laborales, ahora tampoco ;-)

Estamos buscando un programadro Rails con experiencia para un proyecto en funcionamiento, buen clima de trabajo, zona de microcentro y relación de dependencia con posiblidad de crecimiento para una empresa de telecomunicaciones.

Experiencia en BDD rspec,REST y OpenId es un plus.

Enviar mail con cv a jobs [ arroba ] virtualizar.com.ar

Nuevito, recien inagurado por nuestro amigo del otro lado del charco Diego Algorta Casamayou el Grupo de Usuarios Ruby de Uruguay Ya que los argentinos somos un virus maligno que se esparce por todo el mundo, podemos participar no? :-D

Exitos y mantenganos informados y a ver si cruzamos el charco a dar alguna que otra charla o workshop.

GIT (no, la banda no)

April 15th, 2008

(Sé que no soy el único que entendió el chiste del título, asi que a hacerse cargo).

Ahora a lo que nos compete: Acá en OnRails no queríamos ser menos :P, y viendo la gran cantidad de blogs que hablan de GIT, no nos queríamos quedar sin nombrarlo.

There’s a new SCM in town.

Los últimos dos años he usado SVN, con algun que otro problema, pero sin realmente tener algo concreto para quejarme. Antes de SVN trabajé como administrador de ClearCase, que es la herramienta de SCM de Rational, que luego fue comprada por IBM. ClearCase (CC) se caracteriza por muchas cosas (muchas negativas), siendo la burocracia una de ellas. Como admin pude experimentar el sufrimiento de laburar con un esquema complejo, y que no facilitaba el trabajo de los desarrolladores. CC permite un montón de operaciones que en SVN son muy difíciles o muy propensas a generar conflictos. En CC se podían crear muy facilmente los “streams”, que no eran otra cosas que branches, justamente uno de los temas que GIT resuelve por sobre SVN.

Hace un mes comencé a meterme con este “nuevo” SCM, me empapé bastante del tema y puedo decirle las caracteristicas que para mi son más relevantes:

Aclaración al margen: Esto no es una guía sino que simplemente intenta transmitir algunas de las sensaciones generadas en las primeras semanas de uso. Recursos sobran a mi entender.

La creación de branches es trivial.

En SVN era necesario hacer “svn copy ../trunk ../branches/mi_branch”, y luego hacer checkout en otro directorio apuntando a la ruta recién creada, terminando así con varios directorios del mismo repo, cada uno apuntando a un branch diferente.

Con GIT es solo cuestión de ejecutar: git branch mi_branch, y luego hacer checkout mi_branch. Si, sin cambiar de directorio. GIT cambia los archivos automáticamente según el branch seleccionado. Quizás con un ejemplo se vea mejor.

(Mi prompt indica el branch actual, si lo quieren usar copien este link en $HOME/.profile)

driven:~/programming/test_app $ git init
driven:~/programming/test_app $ git add . # Agregando archivos, sino git no se hace cargo
driven:~/programming/test_app $ git commit -a -m "Initial Import" 
driven:~/programming/test_app (master)$ git branch
* master
driven:~/programming/test_app (master)$ git branch req_23568
driven:~/programming/test_app (master)$ git branch
* master
  req_23568
driven:~/programming/test_app (master)$ git checkout req_23568
Switched to branch "req_23568"
driven:~/programming/test_app (req_23568)$

A partir de aquí solo me restaría trabajar en el req_23568, hacer commit lo que sea necesario (los commits son por branch) y luego hacer un rebase del master (nuestro omni presente branch) apuntándolo a req_23568. Cómo sería eso?

driven:~/programming/test_app $ mate . # trabajo, mucho, cambio, pongo, saco
..
driven:~/programming/test_app (req_23568) $ git commit -a -m "Algo 1"
...
driven:~/programming/test_app (req_23568) $ git commit -a -m "Algo 2"
....
driven:~/programming/test_app (req_23568) $ git commit -a -m "Algo 3" 

# laburo con repo remoto? Antes deberia hacer un pull.
driven:~/programming/test_app (req_23568)$ git checkout master 
driven:~/programming/test_app (master)$ git pull # por default es el origin
driven:~/programming/test_app (master)$ git checkout req_23568 # y vuelvo 

driven:~/programming/test_app (req_23568)$ git rebase master # por si alguien estuvo laburando en master
driven:~/programming/test_app (req_23568)$ git checkout master # si todo funciono OK me paso a master
Switched to branch "master"
driven:~/programming/test_app (master)$ git rebase req_23568  # y realizo el rebase 
... mucho ruido ... (ojo, muy útil)
driven:~/programming/test_app (master)$

Nota: Se actualizó acorde a lo sugerido por el estimadísimo Luis Lavena.

Lo que hace rebase es interesante. Rebobina el branch MASTER al momento en que se creo el branch REQ_23568, aplica lo cambios del mismo, y luego aplica todos los commits que se hayan aplicado posteriormente en el branch MASTER.

No hay un servidor centralizado.

Cada uno tiene una copia, y es autónoma de la de los demás. Todas las operaciones se realizan localmente y luego se envían los cambios a los repositorios remotos que uno tenga configurado localmente. Obvio, siempre hay que tener permiso, sino no pasa un byte.

Ignorar archivos es una huevada.

Sólo hace falta crear el archivo .gitignore en el root del repo y cargarlo con entradas que pueden incluir el nombre relativo del elemento a excluir, o wildcards más abarcativos.

driven:~/programming/backoffice (tab_container)$ cat .gitignore 
.DS_Store
*.log
tmp/**/*
config/database.yml
db/*.sqlite3
db/schema.rb
db/schema.sql

Incluye una herramienta excelente para visualizar los branches y cambios aplicados o no.

Se llama gitk. Incluir el parámetro—all para que muestre información sobre todos los branches, y no solo el actual/current.

Muchas cosas más.

Dejo para cada uno que tenga ganas la tarea de investigar el stash, que a mi entender es una idea excelente. Este Linus la tiene clara.

Ah, además se integra con SVN muy facilmente. Podésusarlo localmente y hacer commit contra un repo SVN cuando termines. Para los demás que usen SVN es transparente.

Conclusión preliminar.

GIT es la evolución obligada luego de SVN. En mi caso me facilitó mucho poder trabajar con ciertos temas que requerían atención inmediata y otros que llevaban un poco más de tiempo de desarrollo.

Un branch para cada cosa. A guardar, a guardar, cada cosa en su branch! (bueh, suficiente, no?)

El entusiasmo se debe a que este switcher por fin puede instalar Rails 2.0 en su nueva MacBook usando sólo MacPorts. Dejemos que comparta su alegría con todos nosotros. ¿Alguien más puede aportar su experiencia instalando Rails 2.0 en OSX con Fink? ¿O todos aquí instalan RubyGens "a mano"?

Algunos ya lo saben, otros no, para los que no, nuestro querido amigo Luis Lavena, es el responsable del RubyOneClickInstaller. Este hacker argento ha logrado grandes cosas en varios asptactos, como poder desacoplar a Ruby de las dependencias del Microsoft VC6 pasando ahora a MINGW!

Admirable lo suyo Luis!

Todo nuestro apoyo con el proyecto!

Al existente Grupo Ruby Argentina se suma ahora Tango Rails creado por no exactamente Argentinos :-)

Aquí les dejo el kick-off, me encantaría ir e aportar pero estoy fuera del país aún (eso sí aporto en español).

Eso si muchas charlas serán en inglés. Prfff

Más alla de que me cae mal que sea en inglés, apoyo cualquier tipo de difusión de Rails en nuestro querido país.

La dirección es Córdoba 5110 piso 1 y acá está la agenda:

Tango Rails Kickoff Meeting 3rd of April 2008 19:00 Open discussion/Intros and such 19:30(sharp/en punto) Scaffolds on Steroids: Intro to Active Scaffold in English (Eric Northam) 19:50 Open discussion/Coffee break 20:10 Intro to hosting your apps with Amazon Web Services in English (Tom Addland) 20:35 Closing remarks, comments, and where to go with the group

Pronto pizzaconf en Buenos Aires…. un evento seeeeeeerio

Junto con Rodrigo Orrego de ChileOnRails fuimos convocados por Nicolas Orellana de Webprendedor para armar un pequeño workshop de Ruby on Rails en el evento Webprendedor 2008 en Santiago, Chile.

Quizas el nombre de workshop fué un poco ambicioso y en hora y media no se podía hacer gran cosa.

La sala estuvo llena y fue buena la participación de los asistentes. Tuvimos algunos problemas técnicos con el proyector (datashow) que no logramos que se vea bien, y en el medio de la charla un corte de luz nos dejó sin proyector.

Para que la gente asistente no se quede sin completar el worshop, decidimos continuarlo en el salon de la universidad, donde todos los participantes intersados pudieron completar el workshop.

Aqui esta el pdf con el material utilizado.

Workshop Rails 2008

Aquí los archivos

Más imágenes:

Dimos nuestro primer workshop de Ruby on Rails en Costa Rica y no faltó oportunidad para contactarnos con gente que quiere innovar y charlar de Web 2.0

Web 2.0 posts and comments

Hace tiempo hablamos de FixtureReplacement . En ese entonces tuve toda la intensión de utilizarlo, pero me encontré con un dilema. No soportaba namespaces. Le escribí el flaco que lo desarrlló, intercambiamos algunas líneas, y al mes me comentó la novedad: Finalmente soporta namespaces.

O sea que si ahora tenemos un modelo Admin::Rol, podemos especificar la factory de la siguiente manera:

module FixtureReplacement
    attributes_for :admin_rol, :class => Admin::Rol do |rol|
      rol.nombre = "Guarda"
      rol.permisos << create_admin_permiso
      rol.permisos << create_admin_permiso(:nombre => "Sonar Silbato")
    end

    attributes_for :admin_permiso, :class => Admin::Permiso do |p|
      p.nombre = "Cortar Boletos"
    end
  end

Esto hace la práctica de BDD y TDD mucho más amena.

Más información aquí

Piston On SVN

January 5th, 2008

Hace unos meses comencé a trabajar en un proyecto bastante grande. Éste se compone de varias aplicaciones Rails. Cada aplicación usa algunos plugins típicos como el acts_as_list, acts_as_tree y el acts_as_authenticated, además de otros desarrollados por nosotros. El gran punto fue como mantener todas las versiones de los plugins actualizadas. Para este inconveniente decidí en principio usar la propiedad svn:external de Subversion, pero rapidamente me pareció que no escalaba, al menos para lo que yo necesitaba. Miré un poco por ahí, y me acordé de lo que me había comentado Luis alguna vez: Piston.

Ventajas de utilizar Piston:
  • El código externo se guarda en un único repositorio. Esto disminuye la probabilidad de error al momento del deploy usando Capistrano, ya que la caida de algun repo externo no tiene efecto en el deploy de la aplicación.
  • Las actualizaciones de los componentes externos del repositorio se actualizan cuando uno lo decide, y no cuando se hace svn update.
  • Está escrito en Ruby.

Vamos a los bifes:

Instalar Pistón:

sudo gem install -y piston 

Importación de un recurso externo.

cd MI_APP_RAILS

Si el recurso usa svn:external simplemente es necesario ejecutar:

piston convert

En cambio, si se los copiaron previamente, es necesario removerlos primero.

svn rm vendor/plugins/labeled_form_helper
$ svn commit vendor/plugins/labeled_form_helper -m "Labeled Form Helper eliminado provisoriamente" 

Y luego importarlos con el siguiente comando:

piston import http://svn.techno-weenie.net/projects/plugins/labeled_form_helper/ vendor/plugins/labeled_form_helper
svn commit vendor/plugins/labeled_form_helper -m "Labeled Form Helper Pistoneado" 

Para ver los recursos que Piston maneja:

piston status

Para ver actualizar todos los recursos:

piston update

Simple, no?

NOTA: El Piston no realiza commit de nada. Solo trabaja con la copia actual. Así que después de cada operación, si están conformes con los resultados, solo… svn commit ….

El funcionamiento de Piston es simple. Piston guarda en cada carpeta monitoreada por él unas propiedades (svn) que le indican adonde tiene que ir a buscar la información de actualización a la hora de ejecutar: piston update.

Más información puede ser encontrada aquí.

¿Ya está listo Rails 2.0?

December 7th, 2007

Aparentemente, ya se completó el último grupo de cambios para Rails 2.0 y el inevitable anuncio en weblog.rubyonrails.com estaría a punto de suceder de un momento a otro. Esta deducción se desprende el hecho de que en el reciente Changeset 8328 se "taggeo" el directorio trunk del repositorio de Rails 2.0 como tags/rel_2-0-0 y a que el Milestone 2.0 en el Rails Trac ya aparece como "completado" (!).

Para la PizzaConf armamos este plugin para registración de usuarios.

svn://svn.virtualizar.com.ar/projects/plugins/mephisto_reg/

Esta basado en el de feedback, corre en Mephisto Trunk y Rails Edge.

Es un buen startup para armar plugin de mephisto con la nueva arquitectura de plugins.

Temas a tener en cuenta:

Agregar a config/initalizers/custom.rb ActionController::Routing::Routes.reload! al final

En la primera junta de Rails Chile surgió la idea de armar unas charlas para difundir Ruby on Rails y metodologías ágiles y juntar a la gente interesada para que se conozcan, compartan experiencias, y armemos proyectos.

Luego de la junta, nos pusimos en contacto con Rodrigo de ChileOnRails y armamos esto que denominamos PizzaConf : Charlas sobre Ror, Metodologias ágiles y luego algo de pizza(:P) para que nos vayamos conociendo y quien dice hacer proyectos juntos.

Hasta el momento hay 2 charlas confirmadas “Intro a Ruby on Rails” y “BDD usando Rspec”; luego de las charlas habrá pizza para todos!!.

Si te interesa participar registrate registro en el sitio: para saber cuanta pizza llevamos :P y tb porque sortearemos una polera Rails entre los asistentes registrados!.

Para los Argentinos que esten en Santiago, péguense una vuelta, no importa si programan en Java o en C#, es una buena oportunidad para conocer Ruby on Rails y BDD la metodología que esta desplazando a TDD, vengan y sepan porqué.

Trabajando con los user stories un colega me paso esto donde hablan de FixtureReplacement, lo vi, y me gusto.

Es un factory de instancias ActiveRecord para los tests sean unit testo o rspec.

module FixtureReplacement
    def usuario_attributes
      password = String.random
      {
        :nombre               => "valor",
        :otro                  => "otro valor"
        :otro_mas                => String.random,     # un string random de 10 caracteres
        :uno_mas               => String.random(15), # de 15 caracteres
        :password               => password,
        :password_confirmation  => password,
        :un_belongs_to      => default_pepe        # necesita pepe_attributes definido
      }
    end
  end

Esto nos permitira hacer:

new_usuario: equivalente a Usuario.new(usuario_attributes).

create_usuario: equivalente a Usuario.create!(usuario_attributes).

default_usuario: para usar dentro de definiciones model_attributes; esto retorna un Proc object lo cual permite que la creación de el objeto pueda ser cuando recién se necesita, de esta manera se evita la creación de objetos innecesarios hasta que realmente se necesita.

Pero mejor vean el screencast

FixtureReplacement screencast

Estamos trabajando con User Stories o Historias de usuario en BDD y armamos este gráfico como cheat-sheet para poder armar bien los user stories, aqui se los dejo.

Ya estan online los Slides de la presentacion de Dave Astels en RubyConf07

Referencias:

David Chelimsky

Dan North