Changement de la fonction pour detecter les nouveaux patches.
darcs-hash:20071217063029-af139-f98ea94095b6675734b9acfcd9316f90cbb81109.gz
This commit is contained in:
parent
f1d1f2a477
commit
7839be1f19
1 changed files with 126 additions and 29 deletions
|
@ -27,6 +27,7 @@ Envoie un mail détaillant le dernier patch appliqué à un dépot.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
import commands, os, sys, email
|
import commands, os, sys, email
|
||||||
|
from interactive import *
|
||||||
|
|
||||||
try:
|
try:
|
||||||
from lxml import etree
|
from lxml import etree
|
||||||
|
@ -44,7 +45,7 @@ from email.Utils import formatdate
|
||||||
from email import Encoders
|
from email import Encoders
|
||||||
|
|
||||||
CONF_PATH = "_darcs/third-party/darcs-send-changes"
|
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"
|
ID_FILE = CONF_PATH + "/id"
|
||||||
|
|
||||||
def to_utf8(str):
|
def to_utf8(str):
|
||||||
|
@ -65,7 +66,11 @@ def to_utf8(str):
|
||||||
|
|
||||||
def darcs(args):
|
def darcs(args):
|
||||||
""" Invoque darcs et renvoie sa sortie. """
|
""" 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):
|
def get_patch_properties(hash):
|
||||||
""" Récupère les informations a propos d'un certain patch. """
|
""" 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
|
match_cmd = "--match='hash %s'" % hash
|
||||||
else:
|
else:
|
||||||
match_cmd = "--last 1"
|
match_cmd = "--last 1"
|
||||||
prop = etree.XML(darcs("changes %s --xml-output" % match_cmd))[0]
|
(status, changelog) = darcs("changes %s --xml-output" % match_cmd)
|
||||||
diff = darcs("diff %s --unified" % 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:]
|
diff = diff[diff.find('\ndiff ')+1:]
|
||||||
cwd = os.getcwd()
|
cwd = os.getcwd()
|
||||||
hostname = commands.getoutput('hostname -s')
|
hostname = commands.getoutput('hostname -s')
|
||||||
shortrepo = os.path.basename(cwd)
|
shortrepo = os.path.basename(cwd)
|
||||||
if os.path.exists(ID_FILE):
|
if os.path.exists(ID_FILE):
|
||||||
id = file(ID_FILE).readlines()[0].strip()
|
id = file(ID_FILE).read().strip()
|
||||||
else:
|
else:
|
||||||
id = shortrepo
|
id = shortrepo
|
||||||
return { 'author': prop.attrib['author'],
|
return { 'author': prop.attrib['author'],
|
||||||
|
@ -176,20 +187,85 @@ Les options disponibles sont:
|
||||||
-s, --smtp <serveur> spécifie le serveur smtp à utiliser
|
-s, --smtp <serveur> spécifie le serveur smtp à utiliser
|
||||||
-r, --repo <chemin> spécifie l'emplacement du dépôt
|
-r, --repo <chemin> spécifie l'emplacement du dépôt
|
||||||
-f, --from <hash> hash du premier patch de la série a envoyer
|
-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é.
|
Si aucun destinataire n'est donné, roots@crans.org est utilisé.
|
||||||
""" % { 'name': os.path.basename(sys.argv[0]) })
|
""" % { 'name': os.path.basename(sys.argv[0]) })
|
||||||
sys.exit(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__":
|
if __name__ == "__main__":
|
||||||
import smtplib, getopt
|
import smtplib, getopt
|
||||||
|
|
||||||
smtp = 'localhost'
|
smtp = 'localhost'
|
||||||
repo = None
|
repo = None
|
||||||
from_hash = None
|
from_hash = None
|
||||||
|
interactive = False
|
||||||
|
|
||||||
try:
|
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:
|
except getopt.error, msg:
|
||||||
__usage(unicode(msg))
|
__usage(unicode(msg))
|
||||||
for opt, val in options:
|
for opt, val in options:
|
||||||
|
@ -201,6 +277,8 @@ if __name__ == "__main__":
|
||||||
repo = val
|
repo = val
|
||||||
elif opt in [ '-f', '--from' ]:
|
elif opt in [ '-f', '--from' ]:
|
||||||
from_hash = val
|
from_hash = val
|
||||||
|
elif opt in [ '-i', '--interactive' ]:
|
||||||
|
interactive = True
|
||||||
else:
|
else:
|
||||||
__usage("option inconnue « %s »'" % opt)
|
__usage("option inconnue « %s »'" % opt)
|
||||||
recipient = arg
|
recipient = arg
|
||||||
|
@ -212,31 +290,50 @@ if __name__ == "__main__":
|
||||||
else:
|
else:
|
||||||
while not os.path.exists('_darcs') and os.getcwd() != '/':
|
while not os.path.exists('_darcs') and os.getcwd() != '/':
|
||||||
os.chdir('..')
|
os.chdir('..')
|
||||||
if not os.path.exists('_darcs') and os.getcwd() == '/':
|
if not os.path.exists('_darcs'):
|
||||||
cprint("Pas de dépôt darcs trouvé")
|
cprint("Pas de dépôt darcs trouvé")
|
||||||
sys.exit(1)
|
sys.exit(1)
|
||||||
|
|
||||||
if not from_hash:
|
if not os.path.exists(SEEN_FILE):
|
||||||
if os.path.exists(LAST_SEEN_FILE):
|
# Sélection du patch façon darcs
|
||||||
f = open(LAST_SEEN_FILE)
|
cprint(u"C'est la première fois que vous lancez %s dans ce dépôt." % os.path.basename(sys.argv[0]))
|
||||||
from_hash = f.readlines()[0].strip()
|
c = ask("Que voulez-vous faire ?",
|
||||||
f.close()
|
[("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:
|
else:
|
||||||
from_hash = None
|
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:
|
if len(patches) == 0:
|
||||||
sys.exit(0)
|
sys.exit(0)
|
||||||
for patch in patches:
|
for patch in patches:
|
||||||
cprint("Envoi du patch %s a %s." % (patch['hash'], ", ".join(recipient)))
|
props = get_patch_properties(patch)
|
||||||
send_changes(smtplib.SMTP(smtp), recipient, patch)
|
if props:
|
||||||
if not os.path.exists(CONF_PATH):
|
cprint("Envoi du patch %s a %s." % (props['hash'], ", ".join(recipient)))
|
||||||
p = ""
|
send_changes(smtplib.SMTP(smtp), recipient, props)
|
||||||
for comp in CONF_PATH.split('/'):
|
addseen([patch])
|
||||||
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()
|
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue