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.

Dejar 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.

Dejar 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)   

Dejar 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.

Dejar 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.

Dejar 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] :

Dejar 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ó).

Dejar un comentario

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

Conociendo Factor

Como estoy de vacaciones y soy un geek, no podía hacer otra cosa que aprender un lenguaje de programación nuevo y raro.

Pues bien. Hace meses que estoy dando vueltas como mosca sobre www.factorcode.org bajando los binarios del lenguaje, pero nunca me decidí a comenzar con el aprendizaje.

Pues bien. Hoy estaba aburrido y me puse manos a la obra. Para empezar, Factor tiene unas cuantas peculiaridades:

  • concatenativo
  • basado en pila
  • basado en Forth
  • requiere un procesador con instrucciones SSE 2 (posterior a Pentium 4) . Update ( 10/02/09 ): Si se compila desde el código fuente, se puede correr sobre procesadores más viejos. Las versiones precompiladas de Factorcode son las que requieren las instrucciones especiales.

Lo primero significa en términos rápidos y groseros, que los operandos van primero y el operador al final. Por ejemplo:

(1 + 2) / 5 en Factor se escribe 1 2 + 5 /

Lo segundo indica que la estructura principal de almacenamiento de datos es una pila. Es decir, todos los datos se insertan y quitan de una pila que maneja el lenguaje. Ésto permite simplificar un montón las cosas, sobre todo en lo que es la forma de “decir” las cosas.

Continuando con el ejemplo anterior, lo que sucedió es lo siguiente:

  1. al escribir 1 2 se “pushean” en la pila los elementos 1 y 2
  2. ” + ” es una función que toma dos elementos de la pila y le inserta el resultado, por lo que queda un 3 en la pila.
  3. luego se le inserta un 5, por lo que en la pila queda ” 3 5 “
  4. y finalmente ” / ” toma dos operandos de la pila y “pushea” el resultado nuevamente, por lo que queda ” 3/5 ” (si, queda como fracción, no como punto flotante).

Pero para cosas más interesantes viene lo tercero. Forth es un lenguaje bastante viejo, pero muy visionario en su época. Combina un intérprete interactivo con un compilador. El usuario escribe de manera interactiva las subrutinas que en Forth se denominan “palabras” ( “words” ). Previsiblemente un conjunto de palabras forman un “vocabulario”. Las palabras se compilan, debuggean y reescriben de manera interactiva, todo mediante una máquina virtual.

De la misma manera, en Factor trabajamos en un entorno, definiendo palabras, que trabajan sobre una pila.

Entorno de Factor

Entorno de Factor

Por ejemplo, una secuencia se escribe entre llaves.

{ 1 2 3 4 }

Para definir una función que obtenga el promedio de la secuencia anterior hacemos

: average ( seq -- n ) dup sum swap length / ;

Y por supuesto podemos probar haciendo

{ 1 2 3 4 } average .

que retorna “2+1/2″.

Lo que hace la palabra “average” es duplicar el contenido de la cima de la pila (queda la secuencia repetida), luego hacer la sumatoria del la primer secuencia, y se deposita el resultado en la cima de la pila. Intercambiamos (“swap”) el primer elemento de la pila por el segundo (queda la secuencia en la cima). Obtenemos la longitud de la secuencia y depositamos el resultado en la pila. Finalmente obtenemos el resultado final realizando el cociente entre los dos elementos que hay en la pila.

Por supuesto que esto no demuestra todo el lenguaje ni su potencial, pero mi intención es introducirlos un poco en el tema.

Un punto feo de Factor es que no existe mucha documentación para el principiante. Si bien el lenguaje incluye muchísimo código y documentación, es para gente ya “fluente” en el lenguaje. Los que comenzamos tenemos que ir dilucidando por prueba, error y algún que otro chispazo de inspiración.  Pero la gente de Factor está trabajando en éso. Piensen que el lenguaje todavía está en “beta”, aunque es funcional y ya sirve para realizar un montón de cosas.

Si quieren investigar más al respecto pueden consultar los siguientes enlaces:

http://en.wikipedia.org/wiki/Stack-oriented_programming_language

http://es.wikipedia.org/wiki/Lenguaje_de_programaci%C3%B3n_basado_en_pila

http://concatenative.org/

http://factor-language.blogspot.com/2009/01/advantages-of-concatenative-and-stack.html

http://learnfactor.org/

Esta es una charla de Slava Pestov, el mismísimo creador de Factor. Si entienden inglés, se la recomiendo.

Dejar un comentario

Archivado bajo Computadoras, Factor, Geek, Programacion

Que cosa bonita!

Via Microsiervos

Continuando con mi admiración por las cosas raras, llamativas y frikis, un video de un conjunto de Mandelbrot.

Personalmente, creo que hubiese elegido otra música para acompañar, quizás algún raga… Igual, es precioso.

Si quieren ver otro, hace un tiempo hice un post similar. Es que no me canso de ver esas cositas desarrollarse… ;)

1 comentario

Archivado bajo Freak, Geek, Interés general, Videos

Volví

Decidí volver de mis vacaciones. No sabía que escribir. Pero bueno, no me iba a decidir nunca si me quedaba sentado.

Me salté el día del sysadmin, el día del programador, una pequeña cobertura a las Jornadas Regionales de Software Libre (a las que asistí…. parcialmente :( ), y otras cosas más que podría haber comentado. Espero mejorar este aspecto.

Qué les puedo contar por ahora …

Estuve jugando con Wordle. Es muy divertido! Y si se lo aplica bien, queda espectacular en más de una ocasión/aplicación. Básicamente, crea una imagen a partir de una lista de palabras. Las tipografías, colores y forma de distribución de las palabras queda por cuenta del usuario. El soft es gratis, de hecho es un plugin de Java. Así que es bastante probable que lo puedan correr en su máquina.

Por ejemplo, este es el wordle de este blog

Wordle de Pfactorial

Wordle de Pfactorial

Como podrán ver, hablo mucho del rock, y japonés, YEAH! A ver si seguimos mejorando… :)

Dejar un comentario

Archivado bajo Comentario