Synchronisation de fichiers sur un Mac cloud : Mutagen pour vos projets iOS distants

Mac à distance ·~7 min de lecture

Synchronisation de fichiers sur un Mac cloud : Mutagen pour vos projets iOS distants

Le dépôt du projet approche les 40 Go, et Pods, node_modules et DerivedData réunis pèsent plus lourd que le code source lui-même. Vous ouvrez Xcode en local, avec le projet monté via un partage SMB sur un Mac cloud distant, et voilà que l'indexation tourne pendant plus d'une minute, et changer de branche se bloque au point de vous faire croire à une coupure réseau — c'est le premier mur que rencontrent beaucoup de développeurs dès qu'ils déplacent leur environnement de travail sur un Mac cloud. Monter un partage réseau semble pratique au premier abord, mais l'usage révèle vite que les modèles d'accès aux fichiers des gros projets iOS sont naturellement incompatibles avec les systèmes de fichiers réseau. Cet article détaille comment, sur les nœuds HireVPS, nous avons mis en place une synchronisation bidirectionnelle locale/distante avec Mutagen pour retrouver une expérience proche du local.

Pourquoi le montage d'un partage réseau ne convient pas aux gros projets iOS

Les systèmes de fichiers réseau comme NFS ou SMB partent du principe d'un « accès occasionnel à de gros fichiers ». Or l'indexation de Xcode, SourceKit et le scan du cache CocoaPods font exactement l'inverse : ils effectuent en peu de temps des appels stat, open et close sur des dizaines de milliers de petits fichiers. Chaque opération implique un aller-retour réseau — même avec seulement 20 ms de latence, multiplié par des dizaines de milliers d'appels, cela se traduit par des blocages de plusieurs minutes. Pire encore : la gestion des coupures réseau. Le point de montage se figure littéralement en cas d'instabilité de la connexion, bloquant à la fois le terminal et l'éditeur, ce qui oblige à démonter puis remonter de force.

Comparons trois approches courantes pour mieux visualiser la différence :

Solution Réactivité en temps réel Comportement avec de nombreux petits fichiers Reprise après coupure Cas d'usage adapté
Montage SMB/NFS Forte (toujours à jour) Mauvais, aller-retour réseau par fichier Mauvais, se bloque facilement Lecture/écriture occasionnelle de gros fichiers
Tâche planifiée rsync Faible, avec fenêtre de synchronisation Correct, transfert par lots efficace Bon, il suffit de relancer la tâche Sauvegardes régulières, push unidirectionnel
Synchronisation bidirectionnelle Mutagen Quasi temps réel Bon, cache local + transfert incrémental Bon, reconnexion et reprise automatiques Collaboration bidirectionnelle en développement continu

Une leçon apprise à nos dépens : par simplicité, nous avons d'abord simplement monté le partage, et l'étape « Building workspace » de Xcode a pris en moyenne 15 à 25 secondes de plus. La seule attente quotidienne liée à l'indexation représentait déjà une perte de temps notable pour l'équipe ; après le passage à Mutagen, cette attente a quasiment disparu.

Mettre en place une session de synchronisation bidirectionnelle avec Mutagen

Installation et première connexion

Mutagen se présente sous la forme d'un binaire unique ; aucun service supplémentaire n'est nécessaire en permanence, ni en local ni sur le Mac cloud — l'agent est automatiquement déployé côté distant lors de l'établissement de la connexion. Installez-le d'abord en local :

brew install mutagen-io/mutagen/mutagen
mutagen version

Supposons que SSH soit déjà activé sur votre Mac cloud, avec les identifiants fournis dans l'e-mail de mise en service. Créez une session de synchronisation :

mutagen sync create \
  --name=ios-app \
  --ignore-vcs \
  --symlink-mode=posix-raw \
  /Users/me/Projects/ios-app \
  ssh://devuser@your-cloud-mac-host/Users/devuser/Projects/ios-app

--ignore-vcs permet de sauter automatiquement les objets internes de .git (Git se synchronise mieux via son propre protocole, inutile que Mutagen refasse le travail), et --symlink-mode=posix-raw conserve tels quels les liens symboliques courants dans CocoaPods, sans les convertir.

Règles d'exclusion : les répertoires à ne jamais synchroniser

Il faut absolument créer un fichier .mutagenignore à la racine du projet, sinon la première synchronisation transférera aussi plusieurs Go de répertoires de cache :

DerivedData/
Pods/
.build/
node_modules/
*.xcuserstate
xcuserdata/
.DS_Store

Le point commun de ces répertoires est qu'ils peuvent être régénérés localement de chaque côté. Les synchroniser gaspille de la bande passante et peut en plus provoquer les problèmes décrits dans la section suivante.

Quelques pièges liés à Xcode

Performances observées et gestion des conflits

Au quotidien, une synchronisation incrémentale déclenchée par un enregistrement (modification de quelques fichiers Swift) se termine généralement en une à deux secondes — une sensation proche d'un enregistrement local. La toute première synchronisation complète (des dizaines de milliers de fichiers sources), qui doit parcourir l'arborescence entière, est nettement plus lente ; il est recommandé de la lancer avant de commencer à travailler, plutôt que d'attendre en codant en parallèle.

Côté gestion des conflits, le mode bidirectionnel par défaut est two-way-safe : en cas de conflit, rien n'est écrasé automatiquement, la synchronisation s'arrête et attend une intervention manuelle. C'est plus sûr qu'un mode qui force l'écrasement, mais cela entraîne des pauses fréquentes si les deux côtés modifient le même fichier en même temps. Pour un travail d'équipe, on recommande plutôt :

mutagen sync create \
  --name=ios-app \
  --sync-mode=two-way-resolved \
  --default-file-mode-alpha=0644 \
  /Users/me/Projects/ios-app \
  ssh://devuser@your-cloud-mac-host/Users/devuser/Projects/ios-app

two-way-resolved fait gagner par défaut le côté local (alpha) en cas de conflit. Combiné à la règle « une seule personne modifie le code d'un côté à la fois », cela évite pratiquement toute perte de modification. En cas de véritable conflit sur des ressources binaires (images, polices), mutagen sync list liste les chemins concernés ; il suffit alors de comparer manuellement les horodatages et les tailles de fichiers pour décider laquelle conserver.

Une configuration prête à copier

Mutagen prend en charge un fichier de configuration au niveau du projet. En le plaçant sous le nom mutagen.yml à la racine du projet, chaque membre de l'équipe peut lancer la synchronisation d'une seule commande après avoir cloné le dépôt, sans avoir à retaper tous les paramètres :

sync:
  ios-app:
    alpha: "."
    beta: "ssh://devuser@your-cloud-mac-host/Users/devuser/Projects/ios-app"
    mode: "two-way-resolved"
    ignore:
      vcs: true
      paths:
        - "DerivedData"
        - "Pods"
        - "node_modules"
        - "xcuserdata"
        - ".build"
    symlink:
      mode: "posix-raw"

Voici les commandes courantes à connaître pour l'usage quotidien :

mutagen sync list
mutagen sync monitor ios-app
mutagen sync pause ios-app
mutagen sync resume ios-app
mutagen sync terminate ios-app

monitor est particulièrement utile pour comprendre pourquoi une modification n'a pas été synchronisée : on voit en temps réel à quelle étape (scan, mise en staging, transfert) le processus est bloqué.

Liste de vérification avant mise en production

En passant en revue ces points, l'expérience d'édition sur un Mac cloud se rapproche fortement du local, et l'équipe ne se renverra plus la faute pour savoir « à qui appartient la modification non synchronisée ».

Questions fréquentes

Pourquoi ne pas simplement monter le Mac cloud en SMB ou NFS ?

Un montage réseau transforme chaque accès à un petit fichier (indexation Xcode, recherche Pods) en aller-retour réseau ; ouvrir un gros projet peut alors prendre plusieurs dizaines de secondes. Mutagen garde un cache local et synchronise par incréments, la réactivité de l'éditeur reste proche du local et une coupure réseau ne gèle pas le système de fichiers.

Faut-il synchroniser aussi DerivedData ?

Non. Le cache de modules et les index de DerivedData sont liés à l'architecture de la machine et à des chemins absolus ; les synchroniser déclenche presque toujours une réindexation complète ou des erreurs de build. Ajoutez ce dossier à .mutagenignore et laissez chaque machine le régénérer de son côté.

Que faire en cas de conflit en synchronisation bidirectionnelle ?

Utilisez mutagen sync list pour repérer les chemins en conflit. Pour le code source, le mode two-way-resolved avec priorité au côté local (alpha) suffit dans la plupart des cas ; pour les ressources binaires, comparez manuellement avant de trancher. Lancer git status avant chaque session de synchronisation évite déjà la majorité des conflits.

HireVPS

Essayez dès aujourd'hui un Mac mini dédié dans le cloud

Location à la journée, identifiants SSH/VNC en 2 minutes, configuration évolutive à tout moment.

Louer un Mac mini maintenant