Como resolver conflictos entre dos ramas remotas de un repositorio y su bifurcación (fork) en Git

[programación]

La situación es la siguiente: Tenemos un repositorio remoto en Bitbucket que es el principal, y después tenemos una bifurcación (fork) para cada desarrollador, los cuales suben sus cambios mediante solicitudes de integración (pull request). El problema surge al intentar sincronizar ramas entre los distintos repositorios y aparecen conflictos en remoto.

Solucionar este tipo de conflictos en local es sencillo mediante por ejemplo NetBeans, por lo que la solución pasa por convertir el conflicto remoto en un conflicto local.

Supongamos que la rama conflictiva es feature/nueva-funcionalidad

1. Configuramos el repositorio principal como repositorio remoto

git remote add upstream https://Usuario@bitbucket.org/Propietario/Repositorio-principal.git
git fetch upstream

2. Nos situamos en nuestra rama local

git checkout feature/nueva-funcionalidad

3. Obtenemos los posibles cambios desde nuestro repositorio remoto bifurcado

git merge origin/feature/nueva-funcionalidad

4. Obtenemos los cambio del repositorio principal

git merge upstream/feature/nueva-funcionalidad

5. Aquí aparecerán los conflictos que nos impedían hacer el merge entre repositorios remotos. Resolvemos los conflictos y los anotamos (commit). Al terminar ya podemos subir los cambios a nuestro repositorio remoto bifurcado.

git push origin feature/car-insurance-alert

curl_setopt(): CURLOPT FOLLOWLOCATION cannot be activated when an open_basedir is set

[programación]

El mensaje de error completo es este:

Severity: Warning
Message:  curl_setopt(): CURLOPT_FOLLOWLOCATION cannot be activated when an open_basedir is set
Filename: src/Mandrill.php
Line Number: 68

Este es un problema conocido de la API PHP de Mandrill, y existe un Pull Request con la solución creado en abril de 2014, pero por el motivo que sea, no han añadido la corrección al repositorio principal.

Yo utilizo Composer y Packagist para gestionar las dependencias en mis proyectos, por lo que como solución temporal puedes modificar el fichero Mandrill.php con las correcciones, pero esto significa repetir el mismo proceso en todos los entornos de desarrollo, y es fácil olvidarse de hacerlo cuando han pasado unos meses.

Como solución más robusta, he creado un fork the la librería de Mandrill, y la he subido a Packagist para que pueda ser usada. Es tan sencillo como añadir esto a tus “require” en el composer.json:

"carlos_llongo/mandrill": "dev-master"

O también puedes usar:

composer require "carlos_llongo/mandrill:dev-master"

Como saber si un usuario tiene acceso por SSH

[linux]

Tan fácil como mirar el fichero /etc/passwd

Aquí vemos el listado de usuario con la terminal que tienen asignada. Si la terminal no existe, como por ejemplo /bit/false, el usuario será desconectado inmediatamente al hacer login.

Para solucionarlo, editamos el fichero y le damos un terminal válido, como por ejemplo /bin/bash

La solución original en StackOverflow.

Guardar una cookie con JavaScript puro

[programación]

AngularJS tiene un módulo para guardar cookies, pero por desgracia no permite establecer la fecha de expiración de la cookie, por lo que la cookie es borrada al final de la sesión.

Hay plugins para AngularJS y para JQuery que permite crear cookies de forma sencilla y establecer la fecha de expiración, pero no quería añadir una libraría más solo para guardar una cookie. Así que esta es la forma de hacerlo usando únicamente JavaScript puro:

var dExpirationDate = new Date();
dExpirationDate.setTime(dExpirationDate.getTime() + (365*24*60*60*1000));
var sExpirationDate = "expires=" + dExpirationDate.toUTCString();
document.cookie = "cookieName=cookieValue; " + sExpirationDate;

Recomendaciones de anime – Temporada de otoño 2014

[anime]

Anime de la temporada de otoño 2014

No sabría decir si la calidad del anime está bajando, o si yo me estoy volviendo más crítico, pero cada vez cuesta más encontrar anime que recomendar. Esta temporada ha ocurrido lo que no ha ocurrido en tres años y medio de Recomendaciones de anime, y es que por primera vez no tengo nada que recomendar. La que más posibilidades tenía era Shingeki no Bahamut GENESIS, que la verdad empezó muy bien. Me recordaba a Cowboy Bebop, pero ambientada en un mundo de fantasía medieval. El problema es que a mitad seríe la trama descarrila, y pierde mucho de su interés.

Otra en la que tenía esperanzas era la segunda temporada de Psycho-Pass, pero tras verme tres capítulos perdí el interés. No terminó de engancharme. La sigo teniendo pendiente de ver, así que tal vez cuando la acabe actualizaré mi valoración.

Cómo saber cuando se actualizó una web por última vez

[internet] [programación]

Evidentemente esto solo funcionará en páginas estáticas, pero más de una vez me he encontrado con alguna librería de PHP o JQuery que no mostraban ninguna fecha de última actualización en su web. Para esas situaciones, podemos abrir el Firebug y en la consola escribir lo siguiente:

javascript:alert(document.lastModified)

Saltará una alerta con la fecha de la última modificación.

Comprobar si existe un elemento con AngularJS y ejecutar una función solo si existe

[programación]

Esta es la situación: Queremos ejecutar un plugin de JQuery sobre un elemento que se crea dinámicamente con un ng-repeat dentro una plantilla de AngularJS. Es decir, no podemos inicializar el plugin hasta que se ha cargado la plantilla y se han creado los elementos.

Tenemos un controlador específico para dicha plantilla, por lo que realizando la comprobación aquí, solucionamos la primera parte del problema. Investigando un poco, veo que la solución más popular es asignar una directiva al ng-repeat, que detectará cuando se ejecute la última iteración y lanzará un evento para ser recogido por el controlador, y entonces ya podríamos ahí ejecutar el plugin.

En Stackoverflow tenemos un ejemplo de esta aproximación, y en Nodewiz.biz tenemos otro ejemplo muy similar.

El caso es que esta aproximación me parece tremendamente rebuscada, aunque no dudo que cumple con el espíritu de AngularJS. Mi aproximación es más sencilla, aunque sospecho que no es del todo correcta, y me gustaría mejorarla con el tiempo:

$scope.bTooltipsterExists = false;

$scope.$watch(
function(){
    if(angular.element('.tooltipster').length){
        $scope.bTooltipsterExists = true;
        return true;
    }

    return false;
},
function(){
    if($scope.bTooltipsterExists){
        $(".tooltipster").tooltipster({
            trigger: 'click',
            delay: 0
        });
    }
});

Básicamente tengo un $watch que lo que hace es observar una función. Esta función busca los elementos que se crearán con el ng-repeat y tendrán la clase .tooltipster. La segunda función es la que se ejecuta cuando hay un cambio en el valor devuelto por la primera función. Es decir, cuando la primera función pase de devolver false a devolver true, se ejecutará el plugin.

Añado una segunda comprobación con la variable $scope.bTooltipsterExists porque la primera vez que se ejecuta el $watch, como no tiene una variable de referencia anterior, siempre se ejecuta la segunda función, y con esto lo evitamos.

Reseña de juego – Destiny

[videojuegos]

Últimamente tenía muy abandonados los videojuegos. Estaban saliendo pocas cosas para Xbox 360 y mi PC no da para jugar, así que hace un par de meses me compre una Playstation 4. Mi objetivo es poder pasarme un juego cada mes e iré comentando por aquí mis impresiones de cada uno.

Portada del juego Destiny

Empiezo con Destiny, un juego que tenía un expectación brutal y que estaba destinado a echarle horas y horas jugando con amigos. Esto se cumplió al principio, el sistema de juego es excelente, los gráficos son increíbles y jugando con amigos es muy divertido. El problema es que Destiny deja de ofrecer nuevas experiencias muy rápidamente, y entonces se convierte en una tarea muy repetitiva. Sigue siendo entretenido, de esa misma manera en la que te puedes poner a ver la tele y desconectar un rato, pero siendo que mi tiempo de ocio es limitado y tengo que repartirlo entre múltiples aficiones, repetir lo mismo una y otra vez en Destiny me parece una pérdida de tiempo.

Si hay algo que me decidió a dejar el juego, fue el sistema de loot (los ítems que sueltan los enemigos derrotados). Puedes pasar horas y horas sin obtener nada relevante. Todo el sistema parece estar diseñado para obligarte a invertir una cantidad de tiempo descomunal para lograr una mínima mejora en tu personaje. Todo con el fin de hacerte pensar que el juego es más largo de lo que es, intentando ocultar su falta de contenido.

¿Lo recomiendo? NO

Recomendaciones de anime – Temporada de verano 2014

[anime]

Anime de la temporada de verano 2014

Esta ha sido una temporada cargadita de temas de los que hablar. Empecemos con las decepciones. Tenía muchas ganas de ver la segunda temporada de Sword Art Online. El primer arco argumental de la primera temporada me pareció increíble, de lo que más he disfrutado en los últimos años. El segundo arco resultó ser más flojo, pero daba continuación al primero y me gustó su final. Esta segunda temporada ha sido floja. No mala, ni aburrida, pero creo que la palabra que la describe es “superficial”. Entretenida, pero del montón.

La otra decepción ha sido Tokyo Ghoul. No esperaba nada de esta serie, y me resulto interesante y entretenida. Pero por algún motivo, la temporada termina a mitad del arco argumental. Ni siquiera es un cliffhanger, simplemente se corta la historia, y continuará en enero. Imagino que la seguiré viendo entonces, pero me ha dejado con mal sabor de boca.

Y ahora sí a por las recomendaciones.

Hunter x Hunter

Tras 3 años de emisión y 148 capítulos, ha terminado Hunter x Hunter, unos de mis mangas favoritos. Ya vi la adaptación original de 1999 y sus OVAs, y en su momento me encantaron y continué la historia en los mangas, pero debo reconocer que esta nueva versión ha superado a la original, además de poder ver por fin todo el manga animado. Y ahora que se pude ver entera del tirón, ¡es más recomendable que nunca!

Aldnoah Zero

Para mi, esta ha sido la sorpresa de la temporada. Me ha recordado por momentos a Code Geass, sobre todo por su protagonista y los robots con habilidades especiales. El elenco de personajes es en general bastante bueno, la trama es interesante y no demasiado predecible, y la animación, música y combates son entretenidos. Además, tenemos segunda temporada anunciada para enero, así que no tendremos que esperar mucho para ver como continua la historia.

JoJo’s Bizarre Adventure – Stardust Crusaders

Continua la historia de la familia Joestar, ¡y por fin podemos ver a los Stands en acción! Tampoco tengo nada más que destacar. Simpremente es anime clásico del bueno.

Hanamonogatari

Más monogatari nunca puede ser malo, aunque reconozco que este arco es de los que menos me ha enganchado. Supongo que es porque se centra en Kanbaru, que no es de mis personajes favoritos, y apenas salen el resto de personajes. Pero la historia es buena, la animación y el estilo es al que nos tiene acostumbrados Shaft, y por lo menos nos alivia la espera hasta la llegada de la película.

Montar un entorno de desarrollo a partir de un Git remoto

[linux] [mac] [programación]

En resumen, lo que queremos hacer es un checkout de una o varias ramas del repositorio remoto. Para ello seguimos los siguientes pasos:

1. Crear una carpeta donde tendremos nuestro entorno y entrar en ella.

2. Inicializamos el repositorio:

git init

3. Añadimos la ruta al repositorio remoto:

git remote add origin https://[usuario]@[repositorio]

4. Obtenemos las ramas/tags remotos. En este punto nos pedirá la contraseña del repositorio remoto:

git fetch

5. Hacemos el checkout de la rama con la que queramos trabajar:

git checkout develop

Y listo! A trabajar!