#!/bin/bash /usr/scripts/python.sh # -*- coding: utf-8 -*- import subprocess import sendmail import os import argparse import socket import time DEFAULTS = {"mail_from" : "root@crans.org", "mail_to" : "root@crans.org", "repo" : None} ADDITIONAL_HEADERS = {"X-Mailer" : "/usr/scripts/utils/git-whatsnew", "X-CVSinfo" : "git", "X-GitInfo" : "CRANS"} class GitError(Exception): def __init__(self, msg): Exception.__init__(self, msg) def get_status(with_untracked_files=False): """Récupère le status du dépôt courant. Échoue si on n'est pas dans un dépôt git. -b donne les informations de tracking, mais du coup il y a toujours un output, il faut vérifier si il est relevant""" cmd = ["git", "status", "--porcelain", "-b"] if not with_untracked_files: cmd.append("--untracked-files=no") proc = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE) out, err = proc.communicate() if proc.returncode != 0: raise GitError(err) out = out.decode("utf-8") return out def get_status_silentfail(with_untracked_files=False): """Récupère le status, mais ne renvoie rien si le ``git status`` est essentiellement vide.""" out = get_status(with_untracked_files) if all([len(l) == 0 or l.startswith(u"#") for l in out.split(u"\n")]) and not u"ahead" in out: return u"" else: return out def get_repo(): """Récupère le nom du dossier courant.""" return os.getcwd() def send(out, mail_from, mail_to, debug=False): """Envoie le résultat par mail.""" repo = get_repo() host = socket.gethostname() ADDITIONAL_HEADERS["X-Git-Repository"] = "%s:%s" % (host, repo) subject = u"[git] Whatsnew dans %s sur %s" % (repo, host) sendmail.sendmail(mail_from, [mail_to], subject, out, more_headers=ADDITIONAL_HEADERS, debug=debug) if __name__ == "__main__": parser = argparse.ArgumentParser(usage="./git-whatsnew --to=") parser.add_argument("-f", "--from", action="store", type=str, dest="mail_from", help="Expéditeur du mail") parser.add_argument("-t", "--to", action="store", type=str, dest="mail_to", help="Destinataire du mail") parser.add_argument("-r", "--repository", action="store", type=str, dest="repo", help="Path du dépôt") parser.add_argument("-u", "--untracked", action="store_true", dest="untracked", help="Affiche aussi les fichiers non trackés") parser.add_argument("-w", "--untracked-weekly", action="store_true", dest="untracked_weekly", help="Affiche les fichiers non trackés si on est Lundi") parser.add_argument("-d", "--debug", action="store_true", dest="debug", help="Affiche le mail au lieu de l'envoyer") parser.set_defaults(**DEFAULTS) args = parser.parse_args() # Si un path de dépôt est fourni, on s'y cd if args.repo: os.chdir(args.repo) untracked = args.untracked or (args.untracked_weekly and time.localtime()[6] == 0) out = get_status_silentfail(untracked) if out: send(out, args.mail_from, args.mail_to, args.debug)