Control de versiones con Fossil

En estos días me topé con un sistema de control de versiones distribuido que me pareció interesante, y una buena excusa para actualizar el blog de una buena vez :)

Como si no había ya unos cuantos sistemas de control de versiones, apareció otro más, de la mano de los creadores de SQLite. Lo interesante de este sistema es que aparte incluye una wiki, un sistema de tickets, un servidor web, y un blog. Todo en un sólo ejecutable autocontenido y compacto (alrededor de 1 Mb). Y es software libre!!!

Según el creador, el proyecto surgió a raíz de que no se encontraba conforme con ninguno de los sistemas de control de versiones existentes para lo que él quería realizar. Así que creó a Fossil.

Si lo quieren ver en acción, Tanto la página de SQLite (http://www.sqlite.org/), como la de Fossil misma (http://www.fossil-scm.org/) , son el programa en funcionamiento. Pero ejecutarlo en sus propios sistemas no cuesta nada. Hay ejecutables precompilados para Linux, Mac, Windows y OpenBSD, además de la posibilidad de compilarlo desde los fuentes mismos.

La instalación es realmente sencilla. Simplemente ejecuten el programa. Si lo desean, pueden agregarlo al PATH, para que pueda ser accedido como cualquier otro programa del sistema, pero no es necesario.  Incluso puede funcionar en un “chroot jail” perfectamente.

Todo tanto la configuración como el repositorio quedan dentro de un solo archivo, que es una base de datos SQLite. De hecho, no es necesario que este archivo exista en el mismo directorio que el proyecto que estamos versionando.

La configuración puede ser realizada tanto desde una línea de comandos como utilizando la interfaz web. Esto último es tan simple como escribir en una terminal

fossil ui <nombre-repositorio>

Esto automáticamente lanzará una ventana del navegador con la página de configuración del sistema. En caso de que no funcione debido a una configuración inusual, igual se puede alterar el comportamiento desde la terminal, cambiando el nombre del browser por defecto, y luego continuando normalmente.

Para los que usan Git, es muy simple migrar a Fossil (y viceversa, si se arrepienten). Simplemente con ejecutar

git fast-export --all | fossil import --git new-repo.fossil

desde una terminal, han conseguido migrar el proyecto a Fossil.

Los comandos para trabajar son los usuales de un DVCS.

fossil new <nombre-repositorio>
fossil clone <URL> <nombre-repositorio-local>
fossil add <nombre-de-archivo>
fossil push <URL>
fossil pull <URL>
fossil merge <identificador>

Y hay otros más que están mencionados en la documentación (http://www.fossil-scm.org/index.html/doc/trunk/www/quickstart.wiki).

Si quieren un hosting Fossil en donde ubicar su proyecto, pueden recurrir a http://chiselapp.com/

El aspecto del sitio web ofrecido por Fossil es totalmente configuralble desde la interfaz web. Si bien el aspecto ofrecido por defecto no es lo más bonito del mundo, sí es funcional y prolijo.
Luego probarlo un poco, saqué las siguientes conclusiones

  • Simple en todo sentido. Tampoco es trivial. Pero no abruma al usuario con multitudo de términos y opciones variopintos.
  • Cómodo. Está todo en un solo ejecutable. No hay que agregar paquetes, extensiones, módulos ni nada que se le parezca.
  • Está en inglés solamente. Le falta internacionalización, supongo que para reducir el tamaño del ejecutable.
  • La documentación no está muy desarrollada.  Faltan tutoriales, manuales, o cosas por el estilo. Inclusive la comunidad aún es pequeña. Pero lo que está en el sitio oficial alcanza perfectamente para comenzar a usar el sistema. Por otro lado, si tienen dudas y se manejan con el inglés, el soporte lo reciben directamente de los creadores!!
  • Supongo que los que están acostumbrados a otros vcs’s van a sentir que es medio tosco o le faltan características. Quizás con el tiempo aparezcan extensiones, pero es fácil programar las propias, ya que el formato del repositorio está disponible, y las consultas son en SQL!
  • Excelente para un equipo de trabajo pequeño. Se puede levantar un servidor instantáneamente, y tener un sistema de control de versiones distribuido con todos los chiches que se estilan ahora. Luego es fácil escalar si el proyecto adquiere grandes dimensiones.

Habrá que ver qué le depara el futuro, pero creo que es una opción más que interesante para tener en cuenta.

Deja un comentario

Archivado bajo Computadoras, Programacion, Software-Libre

Belleza de código

Problema: convertir número decimal a romano.

Solución en Clojure:

(defn digit [x y z k]
  (condp = k
    1 [x]
    2 [x x]
    3 [x x x]
    4 [x y]
    5 [y]
    6 [y x]
    7 [y x x]
    8 [y x x x]
    9 [x z]))
(defn tim-roman
  [n]
  (cond
    (= n 0) ""
    (>= n 1000) (cons \M (tim-roman (- n 1000)))
    (>= n 100) (concat (digit \C \D \M (quot n 100)) (tim-roman (mod n 100)))
    (>= n 10) (concat (digit \X \L \C (quot n 10)) (tim-roman (mod n 10)))
    :else (digit \I \V \X n)))
(defn str-roman
  [n]
  (apply str (tim-roman n)))

Solución trasladada a Python:

def digits (x, y, z, cond):
    sw = {
        1: [x],
        2: [x, x],
        3: [x, x, x],
        4: [x, y],
        5: [y],
        6: [y, x],
        7: [y, x, x],
        8: [y, x, x, x],
        9: [x, z],
        }
    return ''.join(sw[cond])

def roman (n):
    if n == 0:
        return ""
    elif n >= 1000:
        return 'M' + roman(n-1000)
    elif n >= 100:
        a, b = divmod(n, 100)
        return digits('C', 'D', 'M', a) + roman(b)
    elif n >= 10:
        a, b = divmod(n, 10)
        return digits('X', 'L', 'C', a) + roman(b)
    else:
        return digits('I', 'V', 'X', n)

Son cosas como esa las que me hacen maravillar y ser feliz por saber programación.

Thread original de la lista de Clojure: http://groups.google.com/group/clojure/browse_thread/thread/eaf67fe94a038af

En sí, el problema tiene cientos de soluciones, pero dependiendo del lenguaje, algunas son más interesantes que otras. Por ejemplo, la versión en Factor (reducida al mínimo indispensable) es así:

CONSTANT: roman-digits
    { "m" "cm" "d" "cd" "c" "xc" "l" "xl" "x" "ix" "v" "iv" "i" }

CONSTANT: roman-values
    { 1000 900 500 400 100 90 50 40 10 9 5 4 1 }

: >roman ( n -- str )
    roman-values roman-digits [
        [ /mod swap ] dip <repetition> concat
    ] 2map "" concat-as nip ;

Fuente: http://gitweb.factorcode.org/gitweb.cgi?p=factor/.git;a=tree;f=basis/roman;hb=HEAD

Es parecida a las anteriores.  Sólamente utiliza algunos símbolos más en la estructura de datos, y por lo tanto reduce la necesidad de bifurcaciones en la definición de la palabra >roman. Simplemente va dividiendo el número y concatenando los resultados a medida que avanza en las iteraciones. Indudablemente, es la más difícil de leer de las tres, pero con un poco de paciencia y sentarse a jugar en el scratchpad de Factor se vuelve simple y claro.

Deja un comentario

Archivado bajo Clojure, Computadoras, Factor, Geek, Programacion, Python

Interfase pythonera a Commandlinefu

Buenas gente!

Hace rato que no escribía :( . Bueno, ahora tengo algo bueno por lo menos para postear, ja ja. Estuve trabajando en una interfase para el espectacular sitio Commandlinefu que a tantos linuxeros/unixeros ha ayudado.

Basado en la API publicada por el sitio, hice este script, que por el momento está en su versión 0.01, pero por lo menos anda. Posiblemente luego le agregue más funciones. Por lo pronto, me falta documentar todo, y darle una función real a los manejadores de json y rss.

Espero que les sirva! Las sugerencias serán bien recibidas.

Saludos a todos.

#    This program is free software: you can redistribute it and/or modify
#    it under the terms of the GNU General Public License as published by
#    the Free Software Foundation, either version 3 of the License, or
#    (at your option) any later version.
#
#    This program is distributed in the hope that it will be useful,
#    but WITHOUT ANY WARRANTY; without even the implied warranty of
#    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
#    GNU General Public License for more details.
#
#    You should have received a copy of the GNU General Public License
#    along with this program.  If not, see <http ://www.gnu.org/licenses/>.

import re
import sys
import urllib
import getopt
import pprint

available_libraries = { 'json':False,
                        'feedparser':False,
                    }

try:
    import json
except ImportError:
    try:
        import simplejson as json
    except ImportError:
        pass
    else:
        available_libraries['json'] = True
else:
    available_libraries['json'] = True

try:
    import feedparser
except ImportError:
    pass
else:
    available_libraries['feedparser'] = True

import string
import binascii

interface_url = string.Template('http://www.commandlinefu.com/commands/${command}/${format}/')

formats = ['json', 'rss', 'plaintext']

browse_all_commands = 'browse/sort-by-votes'

def tagged_commands(a_command, sort_criteria=163):
    return 'tagged/%d/%s' %(sort_criteria, a_command)

def matching_commands(query):
    b64_query = binascii.b2a_base64(query).strip()
    return 'matching/%s/%s' %(query, b64_query)

short_opts = 'fjhst'
long_opts = 'feed json help search tag'.split()

def process_plaintext (data):
    """ Function doc """
    print data.read()

def process_json (data):
    """ Function doc """
    if not available_libraries['json']:
        return
    data_json = json.loads(data.read())
    pprint.pprint(data_json)

def process_rss (data):
    """ Function doc """
    if not available_libraries['feedparser']:
        return
    data_rss = feedparser.parse(data.read())
    pprint.pprint(data_rss)

def main (argv=sys.argv[1:]):

    prefered_format = 'plaintext'
    command_to_query = browse_all_commands

    try:
        opts, args = getopt.getopt(argv, short_opts, long_opts)
    except getopt.GetoptError, err:
        print "Uso:"
        return
    for op, arg in opts:
        if op in ('-f', '--feed'):
            if available_libraries['feedparser']:
                prefered_format = 'rss'
        elif op in ('-j', '--json'):
            if available_libraries['json']:
                prefered_format = 'json'
        elif op in ('-h', '--help'):
            print "help!"
        elif op in ('-s', '--search'):
            try:
                command_to_query = matching_commands(args[0])
            except Exception, e:
                pass
        elif op in ('-t', '--tag'):
            try:
                command_to_query = tagged_commands(args[0])
            except Exception, e:
                pass
        else:
            print "Not implemented, will not handle %s" %op

    process = { 'plaintext': process_plaintext,
                'json': process_json,
                'rss': process_rss,
            }

    url = interface_url.substitute(command=command_to_query, format=prefered_format)
    process[prefered_format](urllib.urlopen(url))

if __name__ == '__main__':
    main()

    sys.exit(0)   

Deja un comentario

Archivado bajo Computadoras, Geek, Linux, Python

Garudagroove

Hacía tiempo que no hacía un post de éstos.

Me encontré, via PinkTentacle, con este artista que aparte de hacer música electrónica tiene unos videos muy buenos. En su canal de Youtube pueden verlos todos, pero personalmente me gustaron éstos.

Deja un comentario

Archivado bajo Arte, Interés general, Japan-is-superior, Japón, Música, Videos

Xmonad, o la belleza austera de lo simple

Ayer me decidí por probar Xmonad, un window manager programado en Haskell.

No voy a cubrir temas de instalación y configuración, porque éso ya está en otros lados. Sölo voy a decir que fué simple, pero que hubo que instalar muchos paquetitos. Conste que a pesar de que uso Ubuntu 8.04, prefiero compilar las cosas desde las fuentes, para estar siempre al día. Si, así de retorcido. Y no, no quiero Gentoo. ;)

La instalación, basada en el sistema de paquetes Cabal de Haskell, fué muy al estilo “configure/make/make-install“, pero según Haskell. Todo funcionó de maravilla, no tuve problemas.

Salvo que, es un sistema muy espartano. Por lo menos en ésta versión.
Comenzamos con una pantalla en negro. Si, nada. Si no se acuerdan los atajos de teclado están fritos, porque a diferencia de otros window managers como Openbox, acá el mouse no tira un menucito ni nada.

This is Sparta

This is Sparta

Así que salvo que vayan preparados, van a tener que rebotar varias veces a su window-manager anterior hasta que lo configuren.

La configuración no es para nada amigable. No hay un lenguage de script simple, es un archivo fuente Haskell, así que para manejarlo hay que saber rudimentos de ése lenguaje para saber que lo que se escribe/edita no va a explotar.

Sin embargo, todo el sistema está documentado de manera sufuciente en la web, y si uno se fija, tiene un montón de archivos de configuración de ejemplo, con los que si se da maña, puede mejorar el aspecto, personalizar atajos de teclado, alterar el comportamiento de Xmonad, etc.

El sistema está diseñado para programadores. La idea es simplicidad máxima, para eficiencia máxima. El eye-candy no existe (digamos que es la antítesis de KDE 4 y similares) salvo el que se ingenie uno, a fuerza de hackear la configuración.

Screenshot de Xmonad

Screenshot de Xmonad

El sistema es muy robusto, a pesar que está todavía en desarrollo (no ha llegado a la versión 1). Para aquellos como yo que aman el minimalismo y la eficiencia a toda costa les va a encantar. El sistema casi no consume recursos, parece mentira! Y por supuesto es super rápido.

El mouse casi no se usa. Se puede manejar todo por teclado. Así que si sin programadores expertos, o power users, sabrán apreciar ésto. Una vez aprendidos los atajos, es todo muy rápido y simple.

Supongo que si mantienen su filosofía, lo que les queda por mejorar es el sistema de instalación y configuración, para que sea menos pedregoso. Es el detalle que faltaría para que esté a la altura de otros manejadores como Openbox.

En resumen, es el sistema que andabas buscando si querés eficiencia y productividad a toda costa.

Deja un comentario

Archivado bajo Comentario, Computadoras, Geek, Haskell, Linux, Software-Libre

Siftables

Desde una de las mecas de la ciencia y la tecnología, en este caso el MIT, llegan unos aparatitos de lo más simpáticos y prometedores. Básicamente son como pequeños módulos parecidos a fichas de algún juego, que incluyen una pantalla y unos cuantos sensores, y permiten trabajar con la información de manera gestual y física, utilizando las manos.  En el sitio [1] se muestran videos de cómo estos pequeños módulos interactúan entre ellos, o con una PC, para catalogar información, crear música como con el ReacTable, etc.

Sospecho que en cuanto se popularice la tecnología de los memristores, estos aparatitos o algunos similares van a ser la manera en la que vamos a interactuar con las computadoras, o mejor dicho, la manera en que vamos a procesar la información. Posiblemente no sea como aquella famosa interfaz de “Minority Report”[2][3], pero a me parece que es más factible a corto plazo.

[1] : http://web.media.mit.edu/~dmerrill/siftables.html

[2] :

[3] :

Deja un comentario

Archivado bajo Ciencia, Comentario, Computadoras, Geek, Interés general, Mundo Real, Videos

Jugando con Gimp y Potrace

Fanart de Gunbuster 01-09

Fanart de Gunbuster 01-09

Basado en un trabajo de Shunya Yamashita, del artbook “Wild Flower”.

El personaje es “Noriko Takaya”, una de las protagonistas de la famosa serie “Gunbuster” de Gainax, la cual fue continuada en la serie Diebuster. Ambas son muy divertidas.

En cuanto a la imagen, salió a partir de tratar de darle un aspecto “vectorizado” al original, luego aplicar “relieve” y finalmente retocar el tema del color general, para terminar el acabado simil “piedra”, (que por cierto no me conforma cómo quedó).

Deja un comentario

Archivado bajo Anime, Arte, Fan-art, Interés general, Japón, Software-Libre