Blog de JA Samitier - Página 2

Algunos trucos git en la terminal

El otro día enseñé a Jorge un par de funciones de mi .zshrc que me facilitan la vida gestionando repositorios git desde la terminal y le gustaron bastante. He pensado que igual también resultan interesantes por aquí.

![imagen teclado]({{ site. url }}/assets/images/2017-01-22-como-uso-la-terminal_guetzli.jpg){: .center-image}

  • Cómo generar un .gitignore automáticamente
function gi() {
	 curl -L -s https://www.gitignore.io/api/$@ >> .gitignore;
}

de esta forma se puede ejecutar gi vagrant java intelliJ para descargar el .gitignore resultado de esa búsqueda en Gitignore.io

  • Cómo listar todos los repositorios (con sus respectivas ramas actuales) presentes en un directorio

function gls() {
    for d in *; do
        if [[ -d "$d" && -e "$d/.git" ]]; then
            echo "$d -> $(cd "$d" && git_prompt_info | sed 's/%//g;s/{//g;s/}//g')"
        fi
    done
}

En uno de los proyectos en los que me encuentro tenemos que trabajar con varios módulos, cada uno de los cuales está en un repositorio git distonto. Muchas veces necesitaba poder saber de un vistazo en qué rama estaba cada uno de estos módulos. Se ve así:

~/.vim/plugged
▶ gls
YouCompleteMe -> master ✔
csapprox -> master ✔
ctrlp.vim -> master ✔
ferret -> master ✔
goyo.vim -> master ✔
jshint.vim -> master ✗
nerdcommenter -> master ✔
nerdtree -> master ✔
plaintasks.vim -> master ✗
tagbar -> master ✔
vim-airline -> master ✔
vim-airline-themes -> master ✔
vim-colorschemes -> master ✔
vim-fugitive -> master ✔
vim-gitgutter -> master ✔
vim-hybrid-material -> master ✔
vim-javascript -> master ✔
vim-jsx -> master ✔
vim-sensible -> master ✔
vim-strip-trailing-whitespaces -> master ✔

Requisito: la función git_prompt_info del plugin git de ohmyzsh

  • Cómo hacer git pull a sus ramas actuales en todos los repositorios dentro de un directorio
function gupd() {
    current_directory=$PWD
    for d in *; do
        if [[ -d "$d" && -e "$d/.git" ]]; then
            cd $d
            echo "$d -> $(git_prompt_info | sed 's/%//g;s/{//g;s/}//g')"
            git fetch
            git pull origin $(git_current_branch)
            cd $current_directory
        fi
    done
}

Por lo mismo que he contado en el punto anterior, a veces necesito bajarme los cambios de unos cuantos repositorios, para lo cual esta función me resulta muy cómoda. Además de listar los repositorios, también los actualiza. Evidentemente para poder hacer esto no puedo tener cambios sin commitear en ninguno de los repositorios.

Requisito: las funciones git_current_branch y git_prompt_info del plugin git de ohmyzsh

Estoy seguro de que puede hacerse mejor, por lo que cualquier comentario o idea será bien recibida :)

Cómo uso la terminal

En el trabajo, las dos aplicaciones en las que más centro mi atención son la terminal, donde hago cosas, y el navegador, donde las pruebo. No me gusta usas demasiadas aplicaciones porque eso me supone tener que aprender configuraciones y formas de trabajar que realmente no aportan demasiado. Además, como en el trabajo uso Mac OS y en casa Ubuntu, es un lío tener que usar distintas aplicaciones para lo mismo solo porque no estén en un sistema operativo u otro. En esta entrada me gustaría describir cómo y por qué uso la terminal.

![imagen de terminal]({{ site.url }}/assets/images/2017-01-22-como-uso-la-terminal_guetzli.jpg){: .center-image}

Primero decir que las dos máquinas donde trabajo son:

  • Mountain Nickel 13", corriendo Ubuntu 16.04 "Xenial Xerus", mi portátil personal.
  • MacBook Pro 13" Retina (2015) corriendo Mac OS 10.11 "El Capitán", mi portátil corporativo

Ambas máquinas disponen de terminales *nix, que desde mi punto de vista es la terminal ideal para un desarrollador. A partir de aquí, intento que el funcionamiento de ambas terminales (y todo el software que corro en ellas) sea lo más similar posible. Además de las herramientas que proporcionan out of the box, yo también incluyo:

  • Zsh: shell alternativa a bash que tiene algunos detalles muy útiles para los que usamos mucho la terminal. En la presentación Why Zsh is Cooler than your Shell se pueden ver alguna de estas ventajas.
  • Oh My ZSH: conjunto de configuraciones y plugins construidas alrededor de zsh. Es algo pesada, pero aporta configuraciones muy convenientes con solo un par de clicks.
  • Vim: Editor de texto extremadamente configurable y eficiente. Lo uso para todo casi todo (vale, para proyectos Java empleo IntelliJ IDEA).
  • Tmux: Multiplexador de la terminal que además permite crear sesiones accesibles por ssh. Es ideal para hacer pair programming.
  • The Silver Searcher: Una herramienta para buscar texto alternativa a grep. Es muy muy muy rápida y sencilla de utilizar. La empleo para buscar y reemplazar código de forma masiva. Un must clarísimo.
  • Git: El sistema de control de versiones distribuído que uso para todos los proyectos, tanto profesionales como personales. Además de eficiente, también tiene un cli que permite hacer todo en la terminal fácilmente. Dejo por aquí la configuración que uso normalmente.

Estas son las herramientas que yo añado, pero uso muchas otras que me provee el sistema, algunas de ellas:

  • tail
  • find
  • grep
  • sed
  • curl
  • ssh
  • top
  • ps

Creo que no me dejo nada.

Nestor suele decir que él no usa un IDE, porque unix es su IDE. Un entorno de desarrollo integrado es una aplicación que agrupa un montón de herramientas (de búsqueda, refactoring, edicion de texto, linters...) que usar conjuntamente para desarrollar software. Unix provee muchas herramientas que si se saben usar a la vez, hacen que no necesites un IDE concreto. Por ejemplo, así es como reemplazo texto masivamente, sin usar el reemplazar de ningún IDE.

ag miVar ~/Development/miProyecto/ -l | xargs sed -i 's/miVar/miNuevaVar/g'

Con ag -l listo todos los ficheros donde encuentro la ocurrencia buscada. Con xargs, le paso este listado a sed, el editor de texto en memoria de unix, al que también le paso la orden de reemplazar la ocurrencia por la nueva palabra a todo el fichero. Lo que gano con esto es:

Resumen de 2016 y propósitos para 2017

Otro año se va y otro post en Internet que habla sobre propósitos. 2016 ha sido un año en el que principalmente he seguido desarrollando mis conocimientos técnicos. He atendido a bastantes eventos (o saraos como diría Dani) como el SOSZ16 o el Codemotion e ¡incluso he sido ponente en el Congreso Web!

![propositos 2017 de jesus angel samitier]({{ site.url }}/assets/images/2017-01-17-Propositos.jpg){: .center-image}

También he aprendido y frikeado haciendo pair con Edu, que es como hacer cursos intensivos. Básicamente ha sido un año de afrontar nuevos retos y terminar de convencerme de que mi trabajo es también mi pasión.

Espero muchas cosas de 2017, o, mejor dicho: espero muchas cosas de mi, en este 2017. Aquí van algunas:

  • Leer más. Una vez que cojo un libro me es difícil dejarlo, pero lo cierto es que me cuesta mucho encontrar momentos para leer.

  • Ir a muchos más conciertos. Este año suenan algunas bandas como Foo Fighters, Dream Theater, Sting... y por supuesto mi apuesta segura de cada año: el Leyendas.

  • Ponerme las pilas con sistemas. Docker ha sido una genial forma de meterme en ese mundo, pero ahora tengo que seguir adelante. Los desarrolladores necesitamos tener conocimientos de sistemas. Este año voy a intentar darle un empujón a ese aspecto.

  • Encontrar el pet project definitivo. Todo apunta a que Francho y yo estaremos ocupados este año :)

  • Seguir adelante con el frontend. Algún día tengo que contar por aquí lo maravilloso que es trabajar con personas como Jorge, gracias a las cuales es imposible irse a casa sin haber aprendido algo nuevo.

Y tú, ¿qué tienes pensado para este año?

Docker en proyectos Java (I). Cómo desplegar una aplicación Java en tomcat usando Docker

De todas las cosas que aprendí en 2016, la que más ha cambiado mi día a día ha sido Docker y, sobretodo, la capacidad orquestación con Docker Compose. La orquestación de máquinas es algo que ya me llamó la atención durante mi paso por Senpai Devs, cuando Néstor nos enseñaba las virguerías que era capaz de hacer para montar diferentes entornos. Esta pretende ser la primera de las entradas sobre cómo monté mi entorno de desarrollo (Java EE + Elastic + Apache + tomcat + SQL Server) completamente sobre Docker. Empezaremos por tomcat.

![Docker]({{ site.url }}/assets/images/docker.svg)

Apache tomcat es el contenedor de servlets mas común a la hora de desplegar aplicaciones Java. Es ligero, no demasiado complejo de configurar y está delante de una comunidad enorme de desarrolladores. Además es software libre, lo cual también es importante.

Antes de empezar la fiesta, hay que tener claro que no estamos levantando máquinas, sino aplicaciones. Si necesitamos levantar 3 aplicaciones java, entonces levantaremos tres tomcats, cada uno en su propio contenedor, con su propia configuración etc. Si una aplicación falla, paramos esa aplicación, dejando las demás funcionando. Es por esto que vamos a usar Docker Compose. Para una sola aplicación no sería necesario, ya que con un docker run podríamos tenerla levantada con un comando, pero la idea de esta serie de entradas es mostrar cómo levanto todo mi entorno de desarrollo, para lo cual si es necesaria la orquestación.

Esto es lo que vamos a hacer:

  • Crear un fichero de orquestación (docker-compose.yml) en el que estableceremos las aplicaciones que vamos a levantar (en este caso solo una llamada portal) y también cómo se construye esa aplicación (en este caso haremos que la construya con el fichero Dockerfile dentro del directorio tomcat).
  • Asociar los puertos del contenedor con los de nuestra máquina. El puerto 8080, el de aplicación, lo asociaremos al 3000, y el puerto 8000, el que usaremos para poder debuggar la ejecución del tomcat, lo asociaremos al 4000.
  • Establecer variables de entorno de nuestra aplicación: Le diremos que use 2Gb de ram.

Además, configuraremos el tomcat para que:

  • Utilice la imagen tomcat:7.0.73-jre7-alpine
  • Abra puerto de debug en el 8000
  • Lea la configuración de la carpeta conf dentro del directorio tomcat

Necesitamos un fichero docker-compose.yml que contenga lo siguiente:

version: '2'
services:
  portal:
    build: tomcat/.
    volumes:
      - ./tomcat/conf:/usr/local/tomcat/conf
      - ./webapps_portal:/usr/local/tomcat/webapps
    environment:
      - 'JAVA_OPTS=-Xmx2g'
    ports:
      - 4000:8000
      - 3000:8080

Además necesitaremos un directorio tomcat con el siguiente fichero:

  • Dockerfile:
FROM tomcat:7.0.73-jre7-alpine

ENV JPDA_ADDRESS=8000
ENV JPDA_TRANSPORT=dt_socket

VOLUME ["/usr/local/tomcat/conf"]
VOLUME ["/usr/local/tomcat/webapps"]

EXPOSE 8009
EXPOSE 8000

CMD ["catalina.sh", "jpda", "run"]

y el directorio conf del tomcat, donde podremos modificar la configuración del tomcat (context, logging...). Además, en el directorio principal necesitaremos también el directorio webapps_portal, donde dejaremos el war que desplegará el tomcat.

La estructura queda así:

.
├── docker_compose.yml
├── tomcat
│   ├── Dockerfile
│   └── conf
└── webapps_portal

Ahora solo nos queda levantarlo con docker-compose up --build -d (El --build solo lo necesitaremos la primera vez que lo levantemos, o cuando hagamos cambios en la configuración).

En la siguiente entrada veremos cómo meterle un apache por delante para poder decidir qué peticiones del apache van al tomcat y cuáles no.