#!/usr/bin/env python # -*- coding: utf-8 mode: python -*- vim:sw=4:sts=4:et:ai:si:sta:fenc=utf-8 import os, sys, re from os import path from argparse import ArgumentParser, REMAINDER from glob import glob USER_CONFDIR = '~/etc/deploy' SYSTEM_CONFDIR = '/var/local/deploy' class EOL(object): __repr__ = __string__ = lambda self: 'EOL' EOL = EOL() class EOF(object): __repr__ = __string__ = lambda self: 'EOF' EOF = EOF() class Lexer(object): file = None lexems = None _inf = None _lcount = None _line = None def __init__(self, file, parse=True): self.file = file if parse: self.parse() def next_line(self): line = self._inf.readline() if line == '': return None if line.endswith("\r\n"): line = line[:-2] elif line.endswith("\n"): line = line[:-1] elif line.endswith("\r"): line = line[:-1] self._lcount += 1 self._line = line return line def is_empty(self): return self._line == '' def isa_comment(self): return self._line[:1] == '#' def isa_squote(self): return self._line[:1] == "'" def isa_dquote(self): return self._line[:1] == '"' RE_SPACE = re.compile(r'\s+') RE_COMMENT = re.compile(r'#.*') def parse_ws(self): mo = self.RE_SPACE.match(self._line) if mo is not None: self._line = self._line[mo.end(0):] mo = self.RE_COMMENT.match(self._line) if mo is not None: self._line = self._line[mo.end(0):] def isa_space(self): return self.RE_SPACE.match(self._line) is not None def isa_comment(self): return self.RE_COMMENT.match(self._line) is not None RE_SQUOTE = re.compile(r"'") def parse_sstring(self): slos = self._lcount lexem = '' self._line = self._line[1:] mo = self.RE_SQUOTE.search(self._line) while mo is None: lexem += self._line if self.next_line() is None: raise ValueError("unterminated quoted string starting at line %i" % slos) lexem += "\n" mo = self.RE_SQUOTE.search(self._line) lexem += self._line[0:mo.start(0)] self._line = self._line[mo.end(0):] return lexem RE_DQUOTE = re.compile(r'"') def parse_dstring(self): slos = self._lcount lexem = '' self._line = self._line[1:] mo = self.RE_DQUOTE.search(self._line) while mo is None: lexem += self._line if self.next_line() is None: raise ValueError("unterminated double-quoted string starting at line %i" % slos) lexem += "\n" mo = self.RE_DQUOTE.search(self._line) lexem += self._line[0:mo.start(0)] self._line = self._line[mo.end(0):] lexem = lexem.replace('\\"', '"') lexem = lexem.replace("\\'", "'") lexem = lexem.replace('\\\\', '\\') return lexem RE_EOS = re.compile(r'''\s|(?>>'. Cela permet de mixer du texte formaté et du texte non formaté. """ def _fill_text(self, text, width, indent): return ''.join([indent + line for line in text.splitlines(True)]) def _split_lines(self, text, width): lines = [''] for line in text.splitlines(): if line.startswith('>>>'): lines.append(line) lines.append('') else: lines[-1] += '\n' + line lines = filter(None, lines) texts = [] for line in lines: if line.startswith('>>>'): line = line[3:] if line: texts.append(line) else: texts.extend(super(FancyHelpFormatter, self)._split_lines(line, width)) return texts AP = ArgumentParser( usage=u"%(prog)s --query FILTER", description=__doc__, formatter_class=FancyHelpFormatter, ) AP.set_defaults(action='query') AP.add_argument('-Q', '--query-action', action='store_const', dest='action', const='query', help=u"Interroger la base de données. C'est l'option par défaut") AP.add_argument('-N', '--nop-action', action='store_const', dest='action', const='nop', help=u"Ne rien faire. Utile pour vérifier si le fichier ne contient pas d'erreur de syntaxe.") AP.add_argument('-P', '--dump-action', action='store_const', dest='action', const='dump', help=u"Afficher le contenu de la base de données.") AP.add_argument('-c', '--config', dest='confname', help=u"Spécifier le nom de la configuration à utiliser. Par défaut, utiliser le nom générique deploy.") AP.add_argument('-q', '--query-type', dest='query_type', help=u"") AP.add_argument('-j', '--object-type', dest='object_type', help=u"") AP.add_argument('-t', '--link-type', dest='link_type', help=u"") AP.add_argument('-p', '--profile', dest='profile', help=u"Spécifier le profil de déploiement") AP.add_argument('-F', '--format', dest='format', help=u"Spécifier le format pour la sortie. La valeur par défaut est shell.") AP.add_argument('-v', '--include-vars', dest='vars', metavar='VARS...', help=u"Spécifier les variables qui doivent être affichées. Par défaut, toutes les variables sont affichées.") AP.add_argument('-o', '--object-vars', action='store_true', dest='object_vars', help=u"Afficher les variables associées aux objets.") AP.add_argument('-d', '--dest-vars', action='store_true', dest='dest_vars', help=u"Afficher les variables associées aux hôtes destination.") AP.add_argument('-l', '--link-vars', action='store_true', dest='link_vars', help=u"Afficher les variables associées aux liens.") AP.add_argument('--of', '--object-func', dest='object_func', metavar='FUNC', help=u"Avec le format shell, spécifier le nom d'une fonction à afficher après les variables associées aux objets.") AP.add_argument('--df', '--dest-func', dest='dest_func', metavar='FUNC', help=u"Avec le format shell, spécifier le nom d'une fonction à afficher après les variables associées aux hôtes destination.") AP.add_argument('--lf', '--link-func', dest='link_func', metavar='FUNC', help=u"Avec le format shell, spécifier le nom d'une fonction à afficher après les variables associées aux liens.") o = AP.parse_args() run_qdd(o)