feat(blog): add magit and commitizen post
continuous-integration/drone/push Build is passing Details

This commit is contained in:
drymer 2020-08-27 20:51:24 +02:00
parent ad91f76ff3
commit ce94958cd5
Signed by: drymer
GPG Key ID: A307D64D5DDFDAAD
3 changed files with 162 additions and 0 deletions

View File

@ -6827,3 +6827,84 @@ if err != nil {
Se lo enseñe a [[https://gnusocial.net/ameba][Ameba]] y como cualquier persona con ojos, se sintió muy ofendida por el "diseño". Por ello, hizo una primera implementación de [[https://bulma.io/][bulma]], un framework CSS como lo es bootstrap. Viendo que se habia tomado la molestia, por sentido de la vergüenza y por que en realidad soy consciente de que la UX es importante, decidí terminar de implementarlo (con mucha ayuda) y aprender bastante de conceptos básicos de html, css y js, que siempre voy muy pez. Y ha quedado algo más cuqui, como se puede ver en la primera imagen.
Poco más que añadir. Go me parece un lenguaje interesante y probablemente siga aprendiendo porque hace ya tiempo que quiero tener algún otro lenguaje a parte de python. Es improbable que Gomic reciba muchas más actualizaciones más allá de añadir más orígenes, pero cualquier sugerencia siempre será bienvenida.
* DONE Estandarizar commits en Magit con commitizen :magit:emacs:git:
:PROPERTIES:
:EXPORT_FILE_NAME: estandarizar-commits-en-magit-con-commitizen
:ARCHIVE_TIME: 2020-08-27 Thu 20:50
:ARCHIVE_FILE: ~/.syncthing/Casa/Proyectos/BadDaemons/content-org/articulos.org
:ARCHIVE_CATEGORY: articulos
:END:
Quién trabaje o contribuya a proyectos de software con otras personas sabrá que a veces el tiempo se va discutiendo chorradas. Un ejemplo típico son las convenciones del código.
Por ejemplo, en python lineas más largas de 79 carácteres (como el pep8 define) o más (ya que no estamos en los 90 y tenemos pantallas de más de 8 pulgadas)? Una lista debería estar en una sola línea o en varias?
Para la mayor parte de los casos no hay respuesta correcta, por que es cuestión de gustos. Por ello, ya hace un tiempo que decidí que paso de dedicar mi tiempo a esto y que otra persona decida por mi. En el caso de los ejemplos anteriores he decidido que sea [[https://github.com/psf/black][black]] quien decida como hacer las cosas. Pero yendo al articulo, he decidido que quién se encargue del formato de mis commits sea [[https://commitizen-tools.github.io/commitizen/][commitizen]].
Alredor del formato de los commits hay mucha historia. Lo idóneo es poner el tipo de cambio, el alcance de este, un título que resuma el cambio, un cuerpo con una explicación más profunda si hace falta y un ticket del gestor de tareas que uses. De esta forma es más fácil ver como evoluciona el código y la lógica que hay detrás. Tiene un añadido y es que si los commits tienen el mismo formato, se pueden generar changelogs de forma automática.
Meter toda esta información no es fácil. Para ello está [[https://commitizen-tools.github.io/commitizen/][commitizen]]. Esta herramienta da lo siguiente:
- [[https://www.conventionalcommits.org/en/v1.0.0/][Implementar una convencion de commits]]
- [[https://semver.org/][Gestión de versiones semántica]]
- [[https://keepachangelog.com/en/1.0.0/][Crear un changelog]]
=cz= es un plugin de git. En vez de usar `git commit` lo que hay que hacer es usar =git cz= y te hace una serie de preguntas que ayudarán a generar el mensaje. Se puede ver un ejemplo en esta imagen:
[[/img/commitizen.gif]]
Pero esta es una herramienta para la terminal, y teniendo emacs, la terminal está obsoleta. Así que veamos como usar esto en Magit. Lo idóneo sería llamar a =git cz= directamente, ya que aunque =cz= define las convenciones, estas se pueden cambiar por proyecto, por lo que generar una plantilla para el commit sin más puede no cubrir todos los casos. Estuve investigando cómo hacerlo pero tendría que haberme metido mucho más en la madriguera del conejo de lo que ya he hecho, por lo que decidí ir a por una solución de compromiso.
Por un lado, hice una plantilla para magit. Esto me servirá para la mayoría de los casos. Pero para cuando no, tengo una función que me deja hacer el commit desde emacs. No usa magit, lo cual es una pena, pero para el caso valdrá. Veamos ambas opciones.
He creado una función que usa [[https://github.com/joaotavora/yasnippet][yasnippet]], un sistema de plantillas. Luego se añade esa función al hook del git-commit y de esta forma cada vez que se haga un commit, se llama a la función:
#+BEGIN_SRC emacs-lisp
(defun daemons/commitizen-template()
"Expand a commitizen template."
(yas-expand-snippet "${1:Select the type of change you are committing: $$(yas-choose-value '(\"fix\" \"feat\" \"docs\" \"style\" \"refactor\" \"perf\" \"test\" \"build\" \"ci\"))}(${2:Scope. Could be anything specifying place of the commit change (users, db, poll): )}): ${3:Subject. Concise description of the changes. Imperative, lower case and no final dot}
${4:Body. Motivation for the change and contrast this with previous behavior}
${5:Footer. Information about Breaking Changes and reference issues that this commit closes}"))
(add-hook 'git-commit-setup-hook #'daemons/commitizen-template)
#+END_SRC
Para llamar a =cz= directamente he usado una función bonica que encontré en reddit (la fuente está en la función) que en resumen usa [[https://github.com/akermu/emacs-libvterm][vterm]] para lanzar una orden arbitrária. Creé la función chorra que llama a esa función con =cz= y ya está.
#+BEGIN_SRC emacs-lisp
(defun phalp/run-in-vterm (command)
"Execute string COMMAND in a new vterm.
From: https://www.reddit.com/r/emacs/comments/ft84xy/run_shell_command_in_new_vterm/
Interactively, prompt for COMMAND with the current buffer's file
name supplied. When called from Dired, supply the name of the
file at point.
Like `async-shell-command`, but run in a vterm for full terminal features.
The new vterm buffer is named in the form `*foo bar.baz*`, the
command and its arguments in earmuffs.
When the command terminates, the shell remains open, but when the
shell exits, the buffer is killed."
(interactive
(list
(let* ((f (cond (buffer-file-name)
((eq major-mode 'dired-mode)
(dired-get-filename nil t))))
(filename (concat " " (shell-quote-argument (and f (file-relative-name f))))))
(read-shell-command "Terminal command: "
(cons filename 0)
(cons 'shell-command-history 1)
(list filename)))))
(with-current-buffer (vterm (concat "*" command "*"))
(vterm-send-string command)
(vterm-send-return)))
(defun daemons/commitizen-gz() (interactive) (phalp/run-in-vterm "git cz commit; exit"))
#+END_SRC
Tiene pinta de que no integraré nunca magit con =cz= dada su dificultad, por lo que probablemente vaya creando plantillas para los commits según el proyecto y buscaré alguna forma de que use una plantilla u otra según el directorio en el que esté. Aún así molaria ver =cz= integrado.

View File

@ -0,0 +1,81 @@
+++
title = "Estandarizar commits en Magit con commitizen"
author = ["drymer"]
lastmod = 2020-08-27T20:47:43+02:00
tags = ["magit", "emacs", "git"]
draft = false
+++
Quién trabaje o contribuya a proyectos de software con otras personas sabrá que a veces el tiempo se va discutiendo chorradas. Un ejemplo típico son las convenciones del código.
Por ejemplo, en python lineas más largas de 79 carácteres (como el pep8 define) o más (ya que no estamos en los 90 y tenemos pantallas de más de 8 pulgadas)? Una lista debería estar en una sola línea o en varias?
Para la mayor parte de los casos no hay respuesta correcta, por que es cuestión de gustos. Por ello, ya hace un tiempo que decidí que paso de dedicar mi tiempo a esto y que otra persona decida por mi. En el caso de los ejemplos anteriores he decidido que sea [black](https://github.com/psf/black) quien decida como hacer las cosas. Pero yendo al articulo, he decidido que quién se encargue del formato de mis commits sea [commitizen](https://commitizen-tools.github.io/commitizen/).
Alredor del formato de los commits hay mucha historia. Lo idóneo es poner el tipo de cambio, el alcance de este, un título que resuma el cambio, un cuerpo con una explicación más profunda si hace falta y un ticket del gestor de tareas que uses. De esta forma es más fácil ver como evoluciona el código y la lógica que hay detrás. Tiene un añadido y es que si los commits tienen el mismo formato, se pueden generar changelogs de forma automática.
Meter toda esta información no es fácil. Para ello está [commitizen](https://commitizen-tools.github.io/commitizen/). Esta herramienta da lo siguiente:
- [Implementar una convencion de commits](https://www.conventionalcommits.org/en/v1.0.0/)
- [Gestión de versiones semántica](https://semver.org/)
- [Crear un changelog](https://keepachangelog.com/en/1.0.0/)
`cz` es un plugin de git. En vez de usar \`git commit\` lo que hay que hacer es usar `git cz` y te hace una serie de preguntas que ayudarán a generar el mensaje. Se puede ver un ejemplo en esta imagen:
{{< figure src="/img/commitizen.gif" >}}
Pero esta es una herramienta para la terminal, y teniendo emacs, la terminal está obsoleta. Así que veamos como usar esto en Magit. Lo idóneo sería llamar a `git cz` directamente, ya que aunque `cz` define las convenciones, estas se pueden cambiar por proyecto, por lo que generar una plantilla para el commit sin más puede no cubrir todos los casos. Estuve investigando cómo hacerlo pero tendría que haberme metido mucho más en la madriguera del conejo de lo que ya he hecho, por lo que decidí ir a por una solución de compromiso.
Por un lado, hice una plantilla para magit. Esto me servirá para la mayoría de los casos. Pero para cuando no, tengo una función que me deja hacer el commit desde emacs. No usa magit, lo cual es una pena, pero para el caso valdrá. Veamos ambas opciones.
He creado una función que usa [yasnippet](https://github.com/joaotavora/yasnippet), un sistema de plantillas. Luego se añade esa función al hook del git-commit y de esta forma cada vez que se haga un commit, se llama a la función:
```emacs-lisp
(defun daemons/commitizen-template()
"Expand a commitizen template."
(yas-expand-snippet "${1:Select the type of change you are committing: $$(yas-choose-value '(\"fix\" \"feat\" \"docs\" \"style\" \"refactor\" \"perf\" \"test\" \"build\" \"ci\"))}(${2:Scope. Could be anything specifying place of the commit change (users, db, poll): )}): ${3:Subject. Concise description of the changes. Imperative, lower case and no final dot}
${4:Body. Motivation for the change and contrast this with previous behavior}
${5:Footer. Information about Breaking Changes and reference issues that this commit closes}"))
(add-hook 'git-commit-setup-hook #'daemons/commitizen-template)
```
Para llamar a `cz` directamente he usado una función bonica que encontré en reddit (la fuente está en la función) que en resumen usa [vterm](https://github.com/akermu/emacs-libvterm) para lanzar una orden arbitrária. Creé la función chorra que llama a esa función con `cz` y ya está.
```emacs-lisp
(defun phalp/run-in-vterm (command)
"Execute string COMMAND in a new vterm.
From: https://www.reddit.com/r/emacs/comments/ft84xy/run_shell_command_in_new_vterm/
Interactively, prompt for COMMAND with the current buffer's file
name supplied. When called from Dired, supply the name of the
file at point.
Like `async-shell-command`, but run in a vterm for full terminal features.
The new vterm buffer is named in the form `*foo bar.baz*`, the
command and its arguments in earmuffs.
When the command terminates, the shell remains open, but when the
shell exits, the buffer is killed."
(interactive
(list
(let* ((f (cond (buffer-file-name)
((eq major-mode 'dired-mode)
(dired-get-filename nil t))))
(filename (concat " " (shell-quote-argument (and f (file-relative-name f))))))
(read-shell-command "Terminal command: "
(cons filename 0)
(cons 'shell-command-history 1)
(list filename)))))
(with-current-buffer (vterm (concat "*" command "*"))
(vterm-send-string command)
(vterm-send-return)))
(defun daemons/commitizen-gz() (interactive) (phalp/run-in-vterm "git cz commit; exit"))
```
Tiene pinta de que no integraré nunca magit con `cz` dada su dificultad, por lo que probablemente vaya creando plantillas para los commits según el proyecto y buscaré alguna forma de que use una plantilla u otra según el directorio en el que esté. Aún así molaria ver `cz` integrado.

BIN
static/img/commitizen.gif Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 684 KiB