3. Sondage
• Qui utilise des githooks dans ses projets?
• Qui a deja écrit des scripts en swift -> /bin/swift my_script.swift ?
• Qui versionne ses scripts githooks sur git ?
4. Git-hooks
C’est quoi
• Des scripts qui sont exécutés lors de commandes Git telles que switch, pull, commit, push,
etc…
• Peuvent être écrits et exécutés en n’importe quel langage de scripts avec un Shebang (#!/
bin/(sh|python|perl|zsh|…)
• Présents à la racine du projet dans le dossier .git/hooks/. Non versionnable. (mais possible
de contourner cette limitation sinon ce talk sert à rien 🤪)
5. Pourquoi versionner ses git-hooks ?
• Font partie du tooling de votre projet
• Plus facile à partager:
• Pas d’oubli de les mettre à jour
• Pas d’annonce d’équipe du style: “Hey, j’ai mis a jour les hooks, vous pouvez les récupérer
(de la) et les mettre dans le bon dossier”
6. Pourquoi les écrire en swift
• Les bienfaits de ce langage VS Script shell ou autres langages non typés
• Langage pratiqué par quasiment la totalité des devs iOS en 2023
• Edition avec Xcode en couleur (et Visual Studio code aussi 💪)
7. Swift Script
Les limites
• Il faut télécharger swift sur Linux et Windows
• Pas d’import -> Pas moyen de mutualiser du code qui se répéterai entre les différents hooks
(très génant pour executer plusieurs script sur un seul hook). La raison pour laquelle on
utilisera pas de liens symboliques pour versionner et exécuter nos git-hooks
• Les guard dans les fonctions avec les exit() ne compile pas (alors que exit() quitte le script,
mais exit() != return).
• On aura besoin de script shell quand même, pour arriver a nos
fi
ns 🤪
9. Fichier
Configure
• Premier script qu’on lance pour
initialiser un projet
• Ecrit en shell
• Initialise nos hooks en “copiant” les
hooks sur git vers le .git/hooks/
• Versionné sur git
#
!
/bin/zsh
cat githooks/utils.swift githooks/post
-
checkout.swift > .git/hooks/post
-
checkout
chmod
+
x .git/hooks/post
-
checkout
cat githooks/utils.swift githooks/post
-
me
r
ge.swift > .git/hooks/post
-
me
r
ge
chmod
+
x .git/hooks/post
-
me
r
ge
cat githooks/utils.swift githooks/p
r
e
-
commit.swift > .git/hooks/p
r
e
-
commit
chmod
+
x .git/hooks/p
r
e
-
commit
cat githooks/utils.swift githooks/p
r
epa
r
e
-
commit
-
msg.swift > .git/hooks/p
r
epa
r
e
-
commit
-
msg
chmod
+
x .git/hooks/p
r
epa
r
e
-
commit
-
msg
cat githooks/utils.swift githooks/p
r
e
-
push.swift > .git/hooks/p
r
e
-
push
chmod
+
x .git/hooks/p
r
e
-
push
10. Configure
Etape 1:
versioning de nos
git-hooks
• On versionne dans un
dossier “githooks” nos git-
hooks et notre
fi
chier swift
common (Utils.swift)
#
!
/bin/zsh
cat githooks/utils.swift githooks/post
-
checkout.swift > .git/hooks/post
-
checkout
chmod
+
x .git/hooks/post
-
checkout
cat githooks/utils.swift githooks/post
-
me
r
ge.swift > .git/hooks/post
-
me
r
ge
chmod
+
x .git/hooks/post
-
me
r
ge
cat githooks/utils.swift githooks/p
r
e
-
commit.swift > .git/hooks/p
r
e
-
commit
chmod
+
x .git/hooks/p
r
e
-
commit
cat githooks/utils.swift githooks/p
r
epa
r
e
-
commit
-
msg.swift > .git/hooks/p
r
epa
r
e
-
commit
-
msg
chmod
+
x .git/hooks/p
r
epa
r
e
-
commit
-
msg
cat githooks/utils.swift githooks/p
r
e
-
push.swift > .git/hooks/p
r
e
-
push
chmod
+
x .git/hooks/p
r
e
-
push
11. Configure
Etape 2:
Concatenation
• On concatène notre utils
puis un hook dans .git/
hooks/ grace a la
redirection >
• Sans l’extension .swift
#
!
/bin/zsh
cat githooks/utils.swift githooks/post
-
checkout.swift > .git/hooks/post
-
checkout
chmod
+
x .git/hooks/post
-
checkout
cat githooks/utils.swift githooks/post
-
me
r
ge.swift > .git/hooks/post
-
me
r
ge
chmod
+
x .git/hooks/post
-
me
r
ge
cat githooks/utils.swift githooks/p
r
e
-
commit.swift > .git/hooks/p
r
e
-
commit
chmod
+
x .git/hooks/p
r
e
-
commit
cat githooks/utils.swift githooks/p
r
epa
r
e
-
commit
-
msg.swift > .git/hooks/p
r
epa
r
e
-
commit
-
msg
chmod
+
x .git/hooks/p
r
epa
r
e
-
commit
-
msg
cat githooks/utils.swift githooks/p
r
e
-
push.swift > .git/hooks/p
r
e
-
push
chmod
+
x .git/hooks/p
r
e
-
push
12. Configure.sh
Etape 3:
Permission
• Chmod +x (droit
d’execution)
#
!
/bin/zsh
cat githooks/utils.swift githooks/post
-
checkout.swift > .git/hooks/post
-
checkout
chmod
+
x .git/hooks/post
-
checkout
cat githooks/utils.swift githooks/post
-
me
r
ge.swift > .git/hooks/post
-
me
r
ge
chmod
+
x .git/hooks/post
-
me
r
ge
cat githooks/utils.swift githooks/p
r
e
-
commit.swift > .git/hooks/p
r
e
-
commit
chmod
+
x .git/hooks/p
r
e
-
commit
cat githooks/utils.swift githooks/p
r
epa
r
e
-
commit
-
msg.swift > .git/hooks/p
r
epa
r
e
-
commit
-
msg
chmod
+
x .git/hooks/p
r
epa
r
e
-
commit
-
msg
cat githooks/utils.swift githooks/p
r
e
-
push.swift > .git/hooks/p
r
e
-
push
chmod
+
x .git/hooks/p
r
e
-
push
13. Configure.sh
Etape 4:
L’auto-update
• post-checkout et post-
merge sont exécutés à
chaque fois qu’on pull,
rebase, merge, switch etc…
//Content of githook/post-checkout.swift (same for
post-merge.swift)
// Begin Refreshing hook
progress(message: "Refreshing githooks…")
// we rexecute the configure
sh("if [[ -e configure ]]; then ./configure; fi")
// End Refreshing hook
14. Git-hook post-
checkout
N’oubliez pas le Shebang en
haut de votre utils.swift
#!/usr/bin/swift
import Foundation
// Utils.swift
let verbose = Bool(ProcessInfo.processInfo.environment["SHPM_GITHOOKS_VERBOSE_MODE"] ?? "false")!
extension String {
// MARK: - String Colors
var red: String { "u{001B}[1;31m 🔴 (self)u{001B}[0;0m" }
var green: String { "u{001B}[1;32m 🟢 (self)u{001B}[0;0m" }
var yellow: String { "u{001B}[1;33m 🟡 (self)u{001B}[0;0m" }
var blue: String { "u{001B}[1;36m 🔵 (self)u{001B}[0;0m" }
var orange: String { "u{001B}[38;5;208m 🟠 (self)u{001B}[0;0m" }
}
// Execute a shell command
@discardableResult
func sh(_ command: String) -> (status: Int32, output: String) {
if verbose {
print("$> (command)")
}
let task = Process()
task.launchPath = "/bin/bash"
task.arguments = ["-c", command]
let pipe = Pipe()
task.standardOutput = pipe
task.launch()
let data = pipe.fileHandleForReading.readDataToEndOfFile()
let output = String(data: data, encoding: .utf8)?.trimmingCharacters(in: .whitespacesAndNewlines)
task.waitUntilExit()
if verbose {
print("output:n(output ?? "")nstatus: (task.terminationStatus)n")
}
return (status: task.terminationStatus, output: output ?? "")
}
func progress(message: String) { print("(tag): (message)".blue) }
// MARK: - END Utils / Beginning Hooks code
// Begin Refreshing hook
progress(message: "Refreshing githooks...")
sh("if [[ -e configure ]]; then ./configure; fi")
// End Refreshing hook
15. Aller plus loin 🚀
• Utiliser brew avec un brew
fi
le pour installer vos outils et faire brew bundle dans con
fi
gure
• Partager Utils.swift (via un git submodule) avec un repo Android