Mise

Mise est un "tooling version management", il permet d'installer la plupart des outils nécessaire au bon fonctionnement d'un development environment. Il permet de "pin" les versions précises de ces outils.

Avec direnv et Docker, Mise fait parti des briques de fondactions que j'utilise pour créer mes development kit.

Site officiel : https://mise.jdx.dev

Alternative à Asdf et aqua


Journaux liées à cette note :

J'ai découvert la méthode NVIM_APPNAME qui permet de lancer des instances cloisonnées de Neovim #neovim, #JaiDécouvert

Il y a plus d'un an, j'ai écrit cette note où je décrivais la méthode que j'avais trouvée après plusieurs itérations pour lancer plusieurs instances Neovim cloisonnées.

J'ai publié cette méthode dans neovim-playground, qui ressemble à ceci :

export XDG_CONFIG_HOME=$(PWD)/config/
export XDG_DATA_HOME=$(PWD)/local/share/
export XDG_STATE_HOME=$(PWD)/local/state/
export XDG_CACHE_HOME=$(PWD)/local/cache/

Je me suis senti un peu bête aujourd'hui en découvrant dans la documentation officielle de Neovim qu'il existe une méthode officielle pour isoler une instance Neovim :

Cette fonctionnalité a été ajoutée dans la version 0.9.0 d'avril 2023, suite à une demande d'utilisateurs qui avaient le même besoin que moi, décrite dans cette issue : NVIM_APPNAME: isolated configuration profiles

Dans cette documentation, #JaiDécouvert comment lancer une application dans un namespace cgroups :

$ systemd-run --user -qt -p PrivateUsers=yes -p BindPaths=/home/user/profile_xy:/home/user/.config/nvim nvim

Je trouve cela plutôt simple.
Coïncidence : j'ai découvert systemd-run il y a 3 mois et depuis, je croise cette commande de plus en plus souvent.

Comme je souhaite lancer un environnement cloisonné Neovim tout en conservant l'accès aux outils de mon terminal (comme ceux installés avec Mise), j'ai choisi d'utiliser la méthode basée sur NVIM_APPNAME.

J'ai testé cette méthode avec succès dans neovim-playground (commit).

Journal du mardi 29 avril 2025 à 22:36 #git, #software-engineering

Depuis un an que j'effectue des missions Freelance, j'ai régulièrement besoin d'effectuer des changements dans des projets pour intégrer mes pratiques development kit, telles que l'utilisation de Mise, .envrc, docker-compose.yml, un README guidé, etc.

Généralement, ces missions Freelance sont courtes et je ne suis pas missionné pour faire des propositions d'amélioration de l'environnements de développement.

En un an, j'ai été confronté à cette problématique à cinq reprises.

Jusqu'à présent, j'ai utilisé la méthode suivante :

  • J'ai intégré mon development kit dans une branche sklein-devkit
  • Cette branche m'a ensuite servi de base pour créer des branches destinées à traiter mes issues, nommées sous la forme sklein-devkit-issue-xxx
  • Et pour finir, je transfère mes commits avec git cherry-pick dans une branche du type issue-xxx que je soumettais dans une Merge Request ou Pull Request.

À la base, ce workflow de développement n'est pas très agréable à utiliser, et devient particulièrement complexe lorsque je dois effectuer des git pull --rebase sur la branche sklein-devkit !

Dans les semaines à venir, pour le projet Albert Conversation, je dois trouver une solution élégante pour gérer un cas similaire. Il s'agit de maintenir des modifications (série de patchs) du projet https://github.com/open-webui/open-webui qui :

  • seront soit intégrées au projet upstream après plusieurs semaines ou mois
  • soit resteront spécifiques au projet Albert Conversation et ne seront jamais intégrées en upstream, comme par exemple l'intégration du Système de Design de l'État.

Je me souviens avoir été marqué par l'histoire du projet Real-Time Linux mentionnée dans l'épisode 118 du podcast de Clever Cloud : les développeurs de Real-Time Linux ont maintenu pendant 20 ans toute une série de patchs avant de finir par être intégrés dans le kernel upstream (source : la conférence "PREEMPT_RT over the years") !

Voici la liste des patchs maintenus par l'équipe Real-Time Linux :

└── patches
    ├── 0001-arm-Disable-jump-label-on-PREEMPT_RT.patch
    ├── 0001-ARM-vfp-Provide-vfp_state_hold-for-VFP-locking.patch
    ├── 0001-drm-i915-Use-preempt_disable-enable_rt-where-recomme.patch
    ├── 0001-hrtimer-Use-__raise_softirq_irqoff-to-raise-the-soft.patch
    ├── 0001-powerpc-Add-preempt-lazy-support.patch
    ├── 0001-sched-Add-TIF_NEED_RESCHED_LAZY-infrastructure.patch
    ├── 0002-ARM-vfp-Use-vfp_state_hold-in-vfp_sync_hwstate.patch
    ├── 0002-drm-i915-Don-t-disable-interrupts-on-PREEMPT_RT-duri.patch
    ├── 0002-locking-rt-Remove-one-__cond_lock-in-RT-s-spin_trylo.patch
    ├── 0002-powerpc-Large-user-copy-aware-of-full-rt-lazy-preemp.patch
    ├── 0002-sched-Add-Lazy-preemption-model.patch
    ├── 0002-timers-Use-__raise_softirq_irqoff-to-raise-the-softi.patch
    ├── 0002-tracing-Record-task-flag-NEED_RESCHED_LAZY.patch
    ├── 0003-ARM-vfp-Use-vfp_state_hold-in-vfp_support_entry.patch
    ├── 0003-drm-i915-Don-t-check-for-atomic-context-on-PREEMPT_R.patch
    ├── 0003-locking-rt-Add-sparse-annotation-for-RCU.patch
    ├── 0003-riscv-add-PREEMPT_LAZY-support.patch
    ├── 0003-sched-Enable-PREEMPT_DYNAMIC-for-PREEMPT_RT.patch
    ├── 0003-softirq-Use-a-dedicated-thread-for-timer-wakeups-on-.patch
    ├── 0004-ARM-vfp-Move-sending-signals-outside-of-vfp_state_ho.patch
    ├── 0004-drm-i915-Disable-tracing-points-on-PREEMPT_RT.patch
    ├── 0004-locking-rt-Annotate-unlock-followed-by-lock-for-spar.patch
    ├── 0004-sched-x86-Enable-Lazy-preemption.patch
    ├── 0005-drm-i915-gt-Use-spin_lock_irq-instead-of-local_irq_d.patch
    ├── 0005-sched-Add-laziest-preempt-model.patch
    ├── 0006-drm-i915-Drop-the-irqs_disabled-check.patch
    ├── 0007-drm-i915-guc-Consider-also-RCU-depth-in-busy-loop.patch
    ├── 0008-Revert-drm-i915-Depend-on-PREEMPT_RT.patch
    ├── 0053-serial-8250-Switch-to-nbcon-console.patch
    ├── 0054-serial-8250-Revert-drop-lockdep-annotation-from-seri.patch
    ├── Add_localversion_for_-RT_release.patch
    ├── ARM__Allow_to_enable_RT.patch
    ├── arm-Disable-FAST_GUP-on-PREEMPT_RT-if-HIGHPTE-is-als.patch
    ├── ARM__enable_irq_in_translation_section_permission_fault_handlers.patch
    ├── netfilter-nft_counter-Use-u64_stats_t-for-statistic.patch
    ├── POWERPC__Allow_to_enable_RT.patch
    ├── powerpc_kvm__Disable_in-kernel_MPIC_emulation_for_PREEMPT_RT.patch
    ├── powerpc_pseries_iommu__Use_a_locallock_instead_local_irq_save.patch
    ├── powerpc-pseries-Select-the-generic-memory-allocator.patch
    ├── powerpc_stackprotector__work_around_stack-guard_init_from_atomic.patch
    ├── powerpc__traps__Use_PREEMPT_RT.patch
    ├── riscv-add-PREEMPT_AUTO-support.patch
    ├── sched-Fixup-the-IS_ENABLED-check-for-PREEMPT_LAZY.patch
    ├── series
    ├── sysfs__Add__sys_kernel_realtime_entry.patch
    └── tracing-Remove-TRACE_FLAG_IRQS_NOSUPPORT.patch

46 files

J'ai été impressionné, je me suis demandé comment cette équipe a réuissi à gérer ce projet aussi complexe sur une si longue durée sans finir par se perdre !

Real-Time Linux n'est pas le seul projet qui propose des versions patchées du kernel, c'est le cas aussi du projet Xen, Openvz, etc.

J'ai essayé de comprendre le workflow de développement de ces projets. Avec l'aide de Claude.ia, il semble que ces projets utilisent un outil comme quilt qui permet de gérer des séries de patchs.

Il semble aussi que Debian utilise quilt pour gérer des patchs ajoutés aux packages :

Quilt has been incorporated into dpkg, Debian's package manager, and is one of the standard source formats supported from the Debian "squeeze" release onwards.

source

J'ai creusé un peu de sujet et à l'aide de Claude.ia j'ai découvert des alternatives "modernes" à quilt.

Après avoir jeté un œil sur chacun de ces projets, j'envisage de créer un playground pour tester Stacked Git.

En attendant de trouver un repository Mise pour PostgreSQL Client Applications #mise, #asdf, #postgresql, #dev-kit, #JaimeraisUnJour

À ce jour, je n'ai pas trouvé de repository Mise ou Asdf pour installer les "Client Applications" de PostgreSQL, par exemple : psql, pg_dump, pg_restore.

Il existe asdf-postgres, mais ce projet me pose quelques problèmes :

  • L'installation basée sur le code source de PostgreSQL avec une phase de compilation qui peut être longue et consommer beaucoup d'espace disque.
  • L'intégralité de PostgreSQL est installée alors que je n'ai besoin que des "Client Applications".

#JaimeraisUnJour créer une repository Mise ou Asdf qui permet d'installer les "Client Applications" en mode binaire. Pour le moment, je n'ai aucune idée sur quels binaires me baser 🤔.

En attendant de créer ou de trouver ce repository, voici ci-dessous mes méthodes actuelles d'installation des "PostgreSQL Client Applications".

Sous MacOS

Sous MacOS, j'utilise Brew pour installer le package libpq qui contient les "PostgreSQL Client Applications".

$ brew install libpq

ou alors pour l'installation d'une version spécifique :

$ brew install libpq@17.4

Sous Fedora

Sous Fedora, j'installe le package PostgreSQL client proposé sur la page "Downloads" officielle de PostgreSQL.
Cette méthode me permet d'installer précisément une version majeure précise de PostgreSQL :

Voici les instructions pour installer la dernière version de PostgreSQL 17 sous Fedora 41 :

$ sudo dnf install -y https://download.postgresql.org/pub/repos/yum/reporpms/F-41-x86_64/pgdg-fedora-repo-latest.noarch.rpm
$ sudo rpm --import https://download.postgresql.org/pub/repos/yum/keys/PGDG-RPM-GPG-KEY-Fedora
$ sudo dnf update -y

Le package nommé postgresql17 contient uniquement les "PostgreSQL Client Applications" :

$ dnf info postgresql17
Mise à jour et chargement des dépôts :
Dépôts chargés.
Paquets installés
Nom                      : postgresql17
Epoch                    : 0
Version                  : 17.4
Version                  : 1PGDG.f41
Architecture             : x86_64
Taille une fois installé : 10.7 MiB
Source                   : postgresql17-17.4-1PGDG.f41.src.rpm
Dépôt d'origine          : pgdg17
Résumé                   : PostgreSQL client programs and libraries
URL                      : https://www.postgresql.org/
Licence                  : PostgreSQL
Description              : PostgreSQL is an advanced Object-Relational database management system (DBMS).
                         : The base postgresql package contains the client programs that you'll need to
                         : access a PostgreSQL DBMS server. These client programs can be located on the
                         : same machine as the PostgreSQL server, or on a remote machine that accesses a
                         : PostgreSQL server over a network connection. The PostgreSQL server can be found
                         : in the postgresql17-server sub-package.
                         :
                         : If you want to manipulate a PostgreSQL database on a local or remote PostgreSQL
                         : server, you need this package. You also need to install this package
                         : if you're installing the postgresql17-server package.
Fournisseur              : PostgreSQL Global Development Group
$ dnf repoquery -l postgresql17 | grep "/bin"
Mise à jour et chargement des dépôts :
Dépôts chargés.
/usr/pgsql-17/bin/clusterdb
/usr/pgsql-17/bin/createdb
/usr/pgsql-17/bin/createuser
/usr/pgsql-17/bin/dropdb
/usr/pgsql-17/bin/dropuser
/usr/pgsql-17/bin/pg_basebackup
/usr/pgsql-17/bin/pg_combinebackup
/usr/pgsql-17/bin/pg_config
/usr/pgsql-17/bin/pg_createsubscriber
/usr/pgsql-17/bin/pg_dump
/usr/pgsql-17/bin/pg_dumpall
/usr/pgsql-17/bin/pg_isready
/usr/pgsql-17/bin/pg_receivewal
/usr/pgsql-17/bin/pg_restore
/usr/pgsql-17/bin/pg_waldump
/usr/pgsql-17/bin/pg_walsummary
/usr/pgsql-17/bin/pgbench
/usr/pgsql-17/bin/psql
/usr/pgsql-17/bin/reindexdb
/usr/pgsql-17/bin/vacuumdb

Installation de ce package :

$ sudo dnf install postgresql17
$ psql --version
psql (PostgreSQL) 17.4

Journal du mardi 25 février 2025 à 14:20 #JaiDécouvert, #OnMaPartagé, #mise, #asdf, #dev-kit

Alexandre vient de partager ce thread : « Asdf Version Manager Has Been Re-Written in Golang »

Je découvre que Asdf n'est pas mort ! La version 0.16.0 publié le 30 janvier 2025 a été réécrite en Golang !

La raison principale semble être une volonté d'amélioration de la vitesse de Asdf :

With improvements ranging from 2x-7x faster than asdf version 0.15.0!

source

Depuis cette date, Mise a publié un benchmark qui compare la vitesse d'exécution de Asdf et Mise : https://mise.jdx.dev/dev-tools/comparison-to-asdf.html#asdf-in-go-0-16.

Comme mon ami Alexandre, certains utilisateurs sont inquiets de voir Mise faire trop de choses :

I tried mise a while back, and the main reason I went away from it is like you said, it does too much. It tries to be asdf, direnv and a task runner. I just want a tool manager, and is the reason why I switched to aquaproj/aqua.

source

J'ai migré de Asdf vers Mise en novembre 2023 et pour le moment, je n'ai pas envie, ni de raison pratique particulière pour retourner à Asdf.
De plus, je suis plutôt satisfait d'avoir remplacé direnv par Mise, voir Je pense pouvoir maintenant remplacer Direnv par Mise 🤞.

Je découvre Fastlane #JaiDécouvert, #iOS, #Android, #MobileDev, #InfrastructureAsCode

Je viens de découvrir le projet Fastlane (https://fastlane.tools/).

fastlane is the easiest way to automate beta deployments and releases for your iOS and Android apps. 🚀 It handles all tedious tasks, like generating screenshots, dealing with code signing, and releasing your application.

source

Je pense que c'est l'outil qui me manquait pour suivre le paradigme configuration as code dans mon "Projet 17 - Créer un POC de création d'une app smartphone avec Capacitor".

Il supporte Android et iOS.

Ce projet a commencé en 2014 par Felix Krause et repris par Google en 2017 : « fastlane is joining Google - Felix Krause ».

Mais, je découvre que Google semble avoir arrêter de financer le développement du projet en 2023 : Google is no longer sponsoring Fastlane | Hacker News.

Depuis, le projet semble être toujours actif avec de nombreuses release : https://github.com/fastlane/fastlane/releases.

Fonctionnalités de Fastlane qui m'intéressent tout particulièrement :

Fastlane permet aussi d'automatiser de nombreuses autres tâches que je n'ai pas encore pris le temps d'explorer : https://docs.fastlane.tools/actions/.


Installation de Fastlane avec Mise que j'ai testée sous Fedora et MacOS :

[tools]
ruby = '3.1.6' # for fastlane
fastlane = "2.226.0"

[alias]
fastlane = "https://github.com/mollyIV/asdf-fastlane.git"

(Toujours aussi pénibles ces outils développés en Ruby 😔)

À noter que sous MacOS j'ai dû lancer :

$ mise install -f fastlane

Parce que lors du premier lancement de mise install, j'ai l'impression qu'il a essayé d'installer fastlane avec l'instance ruby native de l'OS.

J'ai cherché s'il existe une option pour préciser que fastlane doit utiliser ruby installé par Mise, mais je n'ai pas trouvé.


17:05 - Solution pour contourner le problème mentionné ci-dessus :

$ mise install ruby
$ mise install

Journal du mercredi 05 février 2025 à 18:32 #OnMaPartagé, #JaiDécouvert, #python, #package, #mise

Un ami m'a fait découvrir uv (https://github.com/astral-sh/uv).

An extremely fast Python package and project manager, written in Rust.

source

Je trouve cela amusant de constater que Rust prend en charge de plus en plus d'outils pour différents langages 😉.

Le projet a commencé fin 2023.

Voici un thread Hacker News de 200 commentaires à ce sujet qui date de février 2024 : Uv: Python packaging in Rust .

L'article de ce thread contient beaucoup d'éléments intéressants : https://astral.sh/blog/uv

Son nom uv semble être une référence à uvloop.

J'en ai profité pour migrer le playground mise-python-flask-playground de pip vers uv : https://github.com/stephane-klein/mise-python-flask-playground/commit/2f1678798cfc6749dcfdb514a8fe4a3e54739844.

J'ai lancé une installation et effectivement, sa rapidité est très impressionnante :

$ uv pip install -r requirements.txt
Resolved 15 packages in 245ms
Prepared 15 packages in 176ms
Installed 15 packages in 37ms
 + alembic==1.14.1
 + blinker==1.9.0
 + click==8.1.8
 + flask==3.1.0
 + flask-migrate==4.1.0
 + flask-sqlalchemy==3.1.1
 + greenlet==3.1.1
 + itsdangerous==2.2.0
 + jinja2==3.1.5
 + mako==1.3.9
 + markupsafe==3.0.2
 + psycopg2-binary==2.9.10
 + sqlalchemy==2.0.37
 + typing-extensions==4.12.2
 + werkzeug==3.1.3

uv ne propose pas seulement une amélioration de l'installation de packages Python, mais propose beaucoup d'autres choses comme :

Pour cette partie, dans un but d'unification, je continuerai à utiliser Mise pour installer une version précise de Python. De plus, Mise intègre nativement UV : https://mise.jdx.dev/mise-cookbook/python.html#mise-uv

Exemple :

$ uv run example.py

Je pense avoir compris que cela lance ce script avec les dépendances du virtual environment du projet. Un peu comme fonctionne npm, yarn ou pnpm qui permet aux scripts d'utiliser les packages présents dans ./node_modules/.

Par exemple, le linter Python ruff, exemple :

$ uv tool run ruff

J'ai un peu parcouru la documentation de pyproject.toml : https://packaging.python.org/en/latest/guides/writing-pyproject-toml/.

J'ai lu aussi la section uv - Locking environments.

Suite à ces lectures, j'ai migré le playground mise-python-flask-playground vers pyproject.toml : https://github.com/stephane-klein/mise-python-flask-playground/commit/c17216464778df4bc00bf782d5a889cb3f198051.

Je ne suis pas certain que ces commandes soient une bonne pratique :

$ uv pip compile requirements.in -o requirements.txt
$ uv pip install -r requirements.txt

Playground qui présente comment je setup un projet Python Flask en 2025 #dev-kit, #python, #mise, #docker, #WSL, #playground, #software-engineering

Je pense que cela doit faire depuis 2015 que je n'ai pas développé une application en Python Flask !

Entre 2008 et 2015, j'ai beaucoup itéré dans mes méthodes d'installation et de setup de mes environnements de développement Python.

D'après mes souvenirs, si je devais dresser la liste des différentes étapes, ça donnerai ceci :

  • 2006 : aucune méthode, j'installe Python 🙂
  • 2007 : je me bats avec setuptools et distutils (mais ça va, c'était plus mature que ce que je pouvais trouver dans le monde PHP qui n'avait pas encore imaginé composer)
  • 2008 : je trouve la paie avec virtualenv
  • 2010 : j'ai peur d'écrire des scripts en Bash alors à la place, j'écris un script bootstrap.py dans lequel j'essaie d'automatiser au maximum l'installation du projet
  • 2012 : je me bats avec buildout pour essayer d'automatiser des éléments d'installation. Avec le recul, je réalise que je n'ai jamais rien compris à buildout
  • 2012 : j'utilise Vagrant pour fixer les éléments d'installation, je suis plutôt satisfait
  • 2015 : je suis radicale, j'enferme tout l'environnement de dev Python dans un container de développement, je monte un path volume pour exposer le code source du projet dans le container. Je bricole en entrypoint avec la commande "sleep".

Des choses ont changé depuis 2015.

Mais, une chose que je n'ai pas changée, c'est que je continue à suivre le modèle The Twelve-Factors App et je continue à déployer tous mes projets packagé dans des images Docker. Généralement avec un simple docker-compose.yml sur le serveur, ou alors Kubernetes pour des projets de plus grande envergure… mais cela ne m'arrive jamais en pratique, je travaille toujours sur des petits projets.

Choses qui ont changé : depuis fin 2018, j'ai décidé de ne plus utiliser Docker dans mes environnements de développement pour les projets codés en NodeJS, Golang, Python

Au départ, cela a commencé par uniquement les projets en NodeJS pour des raisons de performance.

J'ai ensuite découvert Asdf et plus récemment Mise. À partir de cela, tout est devenu plus facilement pour moi.
Avec Asdf, je n'ai plus besoin "d'enfermer" mes projets dans des containers Docker pour fixer l'environnement de développement, les versions…

Cette introduction est un peu longue, je n'ai pas abordé le sujet principal de cette note 🙂.

Je viens de publier un playground d'un exemple de projet minimaliste Python Flask suivant mes pratiques de 2025.

Voici son repository : mise-python-flask-playground

Ce playground est "propulsé" par Docker et Mise.

J'ai documenté la méthode d'installation pour :

Je précise que je n'ai pas eu l'occasion de tester l'installation sous Windows, hier j'ai essayé, mais je n'ai pas réussi à installer WSL2 sous Windows dans un Virtualbox lancé sous Fedora. Je suis à la recherche d'une personne pour tester si mes instructions d'installation sont valides ou non.

Briques technologiques présentes dans le playground :

Voici quelques petites subtilités.

Dans le fichier alembic.ini j'ai modifié le paramètre file_template parce que j'aime que les fichiers de migration soient classés par ordre chronologique :

[alembic]
# template used to generate migration files
file_template = %%(year)d%%(month).2d%%(day).2d_%%(hour).2d%%(minute).2d%%(second).2d_%%(slug)s

Ce qui donne par exemple :

20250205_124639_users.py
20250205_125437_add_user_lastname.py

Ici le port de PostgreSQL est généré dynamiquement par docker compose :

  postgres:
    image: postgres:17
	...
	ports:
      - 5432 # <= ici

Avec cela, fini les conflits de port quand je lance plusieurs projets en même temps sur ma workstation.

L'URL vers le serveur PostgreSQL est générée dynamiquement par le script get_postgres_url.sh qui est appelé par le fichier .envrc. Tout cela se passe de manière transparente.

J'initialise ici les extensions PostgreSQL :

def init_db():
    db.drop_all()
    db.session.execute(db.text('CREATE EXTENSION IF NOT EXISTS "uuid-ossp"'))
    db.session.execute(db.text('CREATE EXTENSION IF NOT EXISTS "unaccent"'))
    db.session.commit()
    db.create_all()

et ici dans la première migration :

def upgrade():
    op.execute('CREATE EXTENSION IF NOT EXISTS "uuid-ossp";')
    op.execute('CREATE EXTENSION IF NOT EXISTS "unaccent";')
    op.create_table('users',
        sa.Column('id', sa.Integer(), autoincrement=True, nullable=False),
        sa.Column('firstname', sa.String(), nullable=False),
        sa.PrimaryKeyConstraint('id')
    )

Journal du mardi 04 février 2025 à 16:46 #windows, #VirtualBox, #WSL, #JaiDécouvert

Je souhaite créer un playground d'un development kit pour Python + PostgreSQL (via Docker) + Flask + Flask-Migrate, basé sur Mise.

J'ai la contrainte suivante : le development kit doit fonctionner sous MS Windows !

Je me dis que c'est une bonne occasion pour moi de tester Windows Subsystem for Linux 🙂.

Problème : je ne possède pas d'instance MS Windows.

#JaiDécouvert que depuis 2015, Microsoft met à disposition des ISOs officiels de MS Windows :

J'ai testé dans ce playground le lancement d'une Virtual machine MS Windows avec Vagrant : https://github.com/stephane-klein/vagrant-windows-playground.

Cela a bien fonctionné 🙂.

J'ai aussi découvert le repository windows-vagrant qui semble permettre de construire différents types d'images MS Windows avec Packer. Je n'ai pas essayé d'en construire une.

Journal du jeudi 30 janvier 2025 à 12:02 ##JaiDécouvert, #DevOps, #linux, #aide-mémoire, #aide

Note de type #aide-mémoire : contrairement à ~/.zprofile, .zshenv est chargé même lors de l'exécution d'une session ssh en mode non interactif, par exemple :

$ ssh user@host 'echo "Hello, world!"'

Je me suis intéressé à ce sujet parce que mes scripts exécutés par ssh dans le cadre du projet /poc-capacitor/ n'avaient pas accès aux outils mis à disposition par Homebrew et Mise.

J'ai creusé le sujet et j'ai découvert que .zprofile était chargé seulement dans les cas suivants :

  • « login shell »
  • « interactive shell »

Un login shell est un shell qui est lancé lors d'une connexion utilisateur. C'est le type de shell qui exécute des fichiers de configuration spécifiques pour préparer l'environnement utilisateur. Un login shell se comporte comme si tu te connectais physiquement à une machine ou à un serveur.

Un shell interactif est un shell dans lequel tu peux entrer des commandes de manière active, et il attend des entrées de ta part. Un shell interactif est conçu pour interagir avec l'utilisateur et permet de saisir des commandes, d'exécuter des programmes, de lancer des scripts, etc.

ChatGPT

Suite à cela, dans ce commit "Move zsh config from .zprofile to .zshenv", j'ai déplacé la configuration de Homebrew et Mise de ~/.zprofile vers .zshenv.

Cela donne ceci une fois configuré :

$ cat .zshenv
eval "$(/opt/homebrew/bin/brew shellenv)"
eval "$(mise activate zsh)"

Mais, attention, « As /etc/zshenv is run for all instances of zsh ». Je pense que ce n'est pas forcément une bonne idée d'appliquer cette configuration sur une workstation, parce que cela peut "ralentir" légèrement le système en lançant inutilement ces commandes.

ChatGPT me conseille cette configuration pour éviter cela :

# Ne charge Brew et Mise que si on est dans un shell interactif ou SSH
if [[ -t 1 || -n "$SSH_CONNECTION" ]]; then
  eval "$(/opt/homebrew/bin/brew shellenv)"
  eval "$(mise activate zsh)"
fi

Journal du mardi 14 janvier 2025 à 15:08 #JaiDécouvert, #mise

Je viens de découvrir une nouvelle option de configuration Mise :

# .mise.toml
[tools]
node = "20.18.1"
"npm:typescript" = "5.7.3"

Comment l'indique la documentation de Mise, "npm:...." = "..." permet d'installer n'importe quel package npm dans un projet géré par Mise.

Concrètement, ici tsc est accessible directement dans le PATH dans le dossier où est placé .mise.toml.