Changement de la fonction pour detecter les nouveaux patches.

darcs-hash:20071217063029-af139-f98ea94095b6675734b9acfcd9316f90cbb81109.gz
This commit is contained in:
Jeremie Dimino 2007-12-17 07:30:29 +01:00
parent f1d1f2a477
commit 7839be1f19

View file

@ -27,6 +27,7 @@ Envoie un mail détaillant le dernier patch appliqué à un dépot.
"""
import commands, os, sys, email
from interactive import *
try:
from lxml import etree
@ -44,7 +45,7 @@ from email.Utils import formatdate
from email import Encoders
CONF_PATH = "_darcs/third-party/darcs-send-changes"
LAST_SEEN_FILE = CONF_PATH + "/last-seen"
SEEN_FILE = CONF_PATH + "/seen"
ID_FILE = CONF_PATH + "/id"
def to_utf8(str):
@ -65,7 +66,11 @@ def to_utf8(str):
def darcs(args):
""" Invoque darcs et renvoie sa sortie. """
return to_utf8(commands.getoutput("env DARCS_DONT_ESCAPE_8BIT=1 darcs " + args))
return to_utf8(commands.getstatusoutput("env DARCS_DONT_ESCAPE_8BIT=1 darcs " + args))
def darcs_raw(args):
""" Invoque darcs et renvoie sa sortie. """
return commands.getstatusoutput("env DARCS_DONT_ESCAPE_8BIT=0 darcs " + args)
def get_patch_properties(hash):
""" Récupère les informations a propos d'un certain patch. """
@ -73,14 +78,20 @@ def get_patch_properties(hash):
match_cmd = "--match='hash %s'" % hash
else:
match_cmd = "--last 1"
prop = etree.XML(darcs("changes %s --xml-output" % match_cmd))[0]
diff = darcs("diff %s --unified" % match_cmd)
(status, changelog) = darcs("changes %s --xml-output" % match_cmd)
if status != 0 or changelog == "":
return None
prop = etree.XML(changelog)
if len(prop) == 0:
return None
prop = prop[0]
diff = darcs("diff %s --unified" % match_cmd)[1]
diff = diff[diff.find('\ndiff ')+1:]
cwd = os.getcwd()
hostname = commands.getoutput('hostname -s')
shortrepo = os.path.basename(cwd)
if os.path.exists(ID_FILE):
id = file(ID_FILE).readlines()[0].strip()
id = file(ID_FILE).read().strip()
else:
id = shortrepo
return { 'author': prop.attrib['author'],
@ -176,20 +187,85 @@ Les options disponibles sont:
-s, --smtp <serveur> spécifie le serveur smtp à utiliser
-r, --repo <chemin> spécifie l'emplacement du dépôt
-f, --from <hash> hash du premier patch de la série a envoyer
-i, --interactive sélectionne les patches en mode interactif
Si aucun destinataire n'est donné, roots@crans.org est utilisé.
""" % { 'name': os.path.basename(sys.argv[0]) })
sys.exit(0)
def getnew():
'''Renvoie les possibles nouveaux patches'''
if os.access(SEEN_FILE, os.R_OK):
seen=set(map(lambda x: x[0:-1], file(SEEN_FILE).readlines()))
else:
seen=set([])
return set(filter(lambda x: x.endswith(".gz"), os.listdir("_darcs/patches"))) - seen
def addseen(patches):
'''Ajoute des patches aux patches déjà vus'''
if not os.path.exists(CONF_PATH):
p = "."
for comp in CONF_PATH.split('/'):
p = "%s/%s" % (p, comp)
if not os.path.exists(p):
os.mkdir(p)
open(SEEN_FILE, "a+").writelines([patch + "\n" for patch in patches])
def select(patches):
'''Sélection interactive de patches'''
decided = []
ignore = []
while patches:
(status, changelog) = darcs("changes --match='hash %s'" % patches[-1])
if status == 0:
print
print changelog
c = ask("Envoyer ce patch ? (%d/%d)" % (len(decided)+1, len(patches) + len(decided)),
[("YO", "envoyer ce patch"),
("n", "ne pas envoyer ce patch"),
("p", "revenir au patch précédent"),
("e", "envoyer tout les patches suivant"),
("i", "n'envoyer aucun des patches suivant"),
("v", "voir le patch"),
Exit])
if c == "y":
decided.append((True, patches.pop()))
elif c == "n":
decided.append((False, patches.pop()))
elif c == "p":
if decided:
patches.append(decided.pop()[1])
else:
cprint("Déjà au début de la liste!", "rouge")
elif c == "e":
while patches:
decided.append((True, patches.pop()))
elif c == "i":
while patches:
decided.append((False, patches.pop()))
else:
ignore.append(patches.pop())
ask("%d patches à envoyer, accepter ?" % [x[0] for x in decided].count(True),
[("YO", "oui"),
("nq", "non", None, lambda: sys.exit(0))])
for d in decided:
if d[0]:
patches.append(d[1])
else:
ignore.append(d[1])
return patches, ignore
if __name__ == "__main__":
import smtplib, getopt
smtp = 'localhost'
repo = None
from_hash = None
interactive = False
try:
options, arg = getopt.getopt(sys.argv[1:], 'hs:r:f:', [ 'help', 'smtp=', 'repo=', 'from='])
options, arg = getopt.getopt(sys.argv[1:], 'hs:r:f:i', [ 'help', 'smtp=', 'repo=', 'from=', 'interactive'])
except getopt.error, msg:
__usage(unicode(msg))
for opt, val in options:
@ -201,6 +277,8 @@ if __name__ == "__main__":
repo = val
elif opt in [ '-f', '--from' ]:
from_hash = val
elif opt in [ '-i', '--interactive' ]:
interactive = True
else:
__usage("option inconnue « %s »'" % opt)
recipient = arg
@ -212,31 +290,50 @@ if __name__ == "__main__":
else:
while not os.path.exists('_darcs') and os.getcwd() != '/':
os.chdir('..')
if not os.path.exists('_darcs') and os.getcwd() == '/':
cprint("Pas de dépôt darcs trouvé")
sys.exit(1)
if not os.path.exists('_darcs'):
cprint("Pas de dépôt darcs trouvé")
sys.exit(1)
if not from_hash:
if os.path.exists(LAST_SEEN_FILE):
f = open(LAST_SEEN_FILE)
from_hash = f.readlines()[0].strip()
f.close()
else:
from_hash = None
if not os.path.exists(SEEN_FILE):
# Sélection du patch façon darcs
cprint(u"C'est la première fois que vous lancez %s dans ce dépôt." % os.path.basename(sys.argv[0]))
c = ask("Que voulez-vous faire ?",
[("S", "sélectionner les patchs à envoyer/ignorer en mode interactif", "select"),
("e", "tout envoyer", "all"),
("i", "tout ignorer", "none"),
Exit])
if c == "none":
addseen(getnew())
sys.exit(0)
elif c == "all":
patches = getnew()
elif c == "select":
# On récupère la liste des patches triés
patches = [x.attrib['hash'] for x in etree.XML(darcs_raw("changes --xml-output")[1])]
patches, ignore = select(patches)
addseen(ignore)
else:
patches = []
ignore = []
# Tri des patches
for patch in getnew():
(status, changelog) = darcs_raw("changes --xml-output --match='hash %s'" % patch)
try:
prop = etree.XML(changelog)[0]
patches.append((int(prop.attrib['date']), prop.attrib['hash']))
except:
ignore.append(patch)
addseen(ignore)
patches.sort()
patches = [x[1] for x in patches]
if interactive:
patches, _ = select(patches)
patches = get_patches_properties(from_hash)
if len(patches) == 0:
sys.exit(0)
for patch in patches:
cprint("Envoi du patch %s a %s." % (patch['hash'], ", ".join(recipient)))
send_changes(smtplib.SMTP(smtp), recipient, patch)
if not os.path.exists(CONF_PATH):
p = ""
for comp in CONF_PATH.split('/'):
p = "%s/%s" % (p, comp)
if not os.path.exits(p):
os.mkdir(p)
f = open(LAST_SEEN_FILE, "w")
f.write(patches[-1]['hash'])
f.close()
props = get_patch_properties(patch)
if props:
cprint("Envoi du patch %s a %s." % (props['hash'], ", ".join(recipient)))
send_changes(smtplib.SMTP(smtp), recipient, props)
addseen([patch])