>

instant-thinking.de

just enough to get you started and leave you confused

Octopress Build Info - Stats for Geeks

| Kommentare

Damals1, in meiner Diplomarbeit fand sich auf der dritten Seite der folgende Text:

Diese Versionsinformationen wurden bei jedem Erstellen des Dokumentes automagically neu generiert. Dazu habe ich das LaTeX-Paket svn-multi verwendet. Heutzutage läge das ganze natürlich nicht mehr in einem SVN-Repo, denn es gibt ja git und das git-info Paket, würde ansonsten aber ganz genau so funktionieren. Total cool, aber heute geht es nicht um LaTeX und seine Anbindung an Versionskontrollsysteme.

Nämlich vielmehr um folgendes:

Diese Informationen, diese nackten und kalten Zahlen, gaben mir immer ein beruhigendes Gefühl der Sicherheit. Ein wohliges Empfinden des Vorranschreitens. Ein warmes Sentiment der Produktivität. Das ist natürlich sehr geeky, aber so bin ich offenbar gestrickt.

Daneben war diese Versionsnummer auch ein ausgesprochen praktisches Instrument, um die verschiedenen Versionen auseinanderzuhalten, die diversen Korrekturlesern vorlagen.

Fast forward to today: Diese meine Website wohnt in einem git-Repo und verfügt nun ebenfalls über ein paar Informationen, die bei jedem Build automagically in den Footer der Seite eingebaut werden:

Hier hat der getreue Mac mini am 23. August 2012 um zehn vor neun am Abend die Git-Revision 6850343, in deren Verzeichnis, man beachte das Sternchen (*), noch uncommitete Änderungen herumlungerten, genommen und mit Hilfe von Ruby in der Version 1.9undeinpaarzerquetetsche diese Seite zusammengebaut.

Das ganze passiert mithilfe eines neuen Rake tasks, der sich die verschiedenen Werte vom lokalen System zusammensucht und sie dann schliesslich über ein paar Ersetzungen in den Footer schreibt. Der task hört auf den Namen stats_to_footer und schaut so aus:

Rake task for geeky stats
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
desc "Put geeky information into the footer"
task :stats_to_footer do
    puts "## Putting geeky stats into the footer"
    build_ruby_version="#{RUBY_ENGINE}-#{RUBY_VERSION}-p#{RUBY_PATCHLEVEL}"
    build_host=`hostname`.gsub(/\n/,"")
    build_time=Time.now.strftime("%F %T")
    build_git_revision=`git --git-dir=#{git_dir} --work-tree=#{git_work_tree} log --pretty=format:'%h' -n 1i`
    build_git_status=`git --git-dir=#{git_dir} --work-tree=#{git_work_tree} status 2> /dev/null | tail -n1`.gsub(/\n/,"")
    if build_git_status == 'nothing to commit (working directory clean)'
            build_git_dirty=''
    else
            build_git_dirty='*'
    end

    puts "Build with " + build_ruby_version
    puts "on " + build_host
    puts "at " + build_time
    puts "out of git revision " + build_git_revision + build_git_dirty

    footer=IO.read("#{source_dir}/_includes/custom/footer.html")
    footer.sub!(/(^Build with).*/, "\\1 <code>#{build_ruby_version}</code>")
    footer.sub!(/(^on).*/, "\\1 <code>#{build_host}</code>")
    footer.sub!(/(^at).*/, "\\1 <code>#{build_time}</code>")
    footer.sub!(/(^out of Git revision).*/, "\\1 <code>#{build_git_revision}#{build_git_dirty}</code>")
    File.open("#{source_dir}/_includes/custom/footer.html", 'w') do |f|
        f.write footer
    end
end

Das Sternchen * als Indikator für git_dirty habe ich aus meinem Prompt2 übernommen, der mir die aktuelle Branch und eben eventuell noch nicht comittete Änderungen anzeigt3, wenn ich mich gerade in einem git-Repo befinde:

Example of my prompt
1
ruby-1.9.2-p290 ~/instant-thinking > [master*]

Die Aufrufe von git sehen mit den Optionen für --git-dir und --work-tree ausserdem ein bisschen funky aus. Das kommt daher, dass sie auch dann funktionieren müssen, wenn sie von einem anderen Verzeichnis als dem git-Repo aufgerufen werden. Das liegt natürlich an launchd, der diese Seite zuverlässig automatisiert zusammenbaut. Deswegen werden in dem Rakefile auch noch diese beiden Variablen definiert, die die Pfade zu den von git benötigten Ordnern relativ zum Octopress-Ordner definieren:

Git variables in Rakefile
1
2
git_dir	        = ".git"      # Git dir to access git status and log from outside the working dir
git_work_tree   = "."         # Git worktree to access git status and log from outside the working dir

Und schlussendlich wird der task noch in die Reihe der tasks für die Erstellung und das Deployment aufgenommen. In dem folgenden Beispiel wird der generische gen_deploy Task gezeigt, daneben gibt es noch einen prod_gen_deploy in dem der Task auf die selbe Art und Weise integriert ist:

Modified gen_deploy task
1
2
3
desc "Generate website and deploy"
task :gen_deploy => [:integrate, :stats_to_footer, :generate, :deploy] do
end

Und das war es im Grunde auch schon. Man kann sicher die regulären Ausdrücke noch ein wenig sicherer gestalten und vielleicht kommt man auch noch irgendwie drumrum, dass nun ständig Änderungen an footer.html zu commiten sind. Und wo ich so gerade drüber nachdenke, die verwendete Branch wäre auch noch eine Überlegung wert…

Na mal sehen, fürs erste funktioniert das schon sehr gut und ich habe wieder dieses Geek High, wenn ich den Footer von instant-thinking.de betrachte.

(Idee via: ariejan.net)

  1. Jungejunge, ist das schon wieder lange her…

  2. Ich muss echt mal meine dotfiles aufräumen und veröffentlichen…

  3. Und in diesem Falle ausserdem noch die aktuell verwendete Ruby-Version…

Comments