Descarga de katas de codewars

2017/05/07

Se busca crear un script para descargar los katas del sitio codewars.

La información a descargar será la siguiente que se visualiza cuando se realiza un kata:

  1. Instrucciones.
  2. Código de ejemplo. Suele ser el encabezado de la función a implementar.
  3. Tests de ejemplo. Suelen ser los test iniciales para probar la función.

Para descargar la información probaremos utilizar la API brindada por codewars, especificamente https://dev.codewars.com/#post-train-code-challenge.

Como ejemplo realizamos una prueba de invocación a la api utilizando el shell:

$ accesstoken="xxx" # Ver "API Access Token" en "https://www.codewars.com/users/edit"
$ slug="a-rule-of-divisibility-by-13"
$ language="c"
$ output=$(curl "https://www.codewars.com/api/v1/code-challenges/${slug}/${language}/train" -X POST -H "Authorization: $accesstoken")
$ echo $output | jq -r '.description'
$ echo $output | jq -r '.session.setup'
$ echo $output | jq -r '.session.exampleFixture'

Para el script se busca que los archivos se descarguen en un directorio con nombre slug_language. Se agrega el sufijo _language ya que un mismo kata puede realizarse en varios lenguajes.

Al codificar el script se debió tener en cuenta:

  1. La extensión de los archivos se debe obtener a partir del nombre del lenguaje. Esto se realiza mediante una función language2extension que utiliza un case para transladar el nombre del lenguaje a la extensión de archivos utilizada por este.

  2. Se encontró que en caso de utilizar un slug o language inválido la api de codewars devuelve un código HTTP 500 y el mensaje con content-type text/html. Por esto se modifica la invocación de curl para que agregue los cabezales HTTP del response mediante el parámetro --include.

    Para verificar el código de error se utiliza: [ 200 != "$(echo "$output" | head -n +1 | cut -d' ' -f2)" ].

    Para extraer el body se utiliza sed: echo "$output" | sed '1,/^\r$/d'.

  3. La descripción devuelta para los katas no tienen el nombre del problema, por lo que en el archivo description.md se agrega al principio un cabezal con el nombre del kata, el slug utilizado en negritas y una linea horizontal:

    cat <<END
    # $(echo "$body" | jq -r '.name')
    
    **($slug)**
    
    ---
    
    END
    
  4. Se genera el script run.sh para ejecutar el kata, basado en el post [Uso de codewars offline][!a!post-codeswars-offline]:

    $ mkdir -p ~/src
    $ (cd ~/src; git clone git@github.com:Codewars/codewars-runner-cli.git)
    $ docker-compose -f ~/src/codewars-runner-cli/docker-compose.yml \
        run --rm $language -c "$(cat solution.$extension)" -f "$(cat tests.$extension)"
    

El script completo está disponible en el archivo codewars-kata-download.