From 1021e7d68e8c66a5c858d2e8ca18f4f2f4126160 Mon Sep 17 00:00:00 2001 From: Doug Hellmann Date: Thu, 27 Nov 2014 20:01:50 +0000 Subject: [PATCH] add grep command --- aeromancer/cli/grep.py | 31 +++++++++++++++++++++++++++++++ aeromancer/db/connect.py | 16 +++++++++++++++- aeromancer/project.py | 14 ++++++++++++++ setup.cfg | 1 + 4 files changed, 61 insertions(+), 1 deletion(-) create mode 100644 aeromancer/cli/grep.py diff --git a/aeromancer/cli/grep.py b/aeromancer/cli/grep.py new file mode 100644 index 0000000..696bd44 --- /dev/null +++ b/aeromancer/cli/grep.py @@ -0,0 +1,31 @@ +from __future__ import print_function + +import logging +import os + +from aeromancer import project + +from cliff.command import Command + + +class Grep(Command): + """Search the contents of files""" + + log = logging.getLogger(__name__) + + def get_parser(self, prog_name): + parser = super(Grep, self).get_parser(prog_name) + parser.add_argument('pattern', + action='store', + help='regular expression', + ) + return parser + + def take_action(self, parsed_args): + session = self.app.get_db_session() + pm = project.ProjectManager(session) + for r in pm.grep(parsed_args.pattern): + line_num, content, filename, project_name = r + print('%s/%s:%s:%s' % + (project_name, filename, line_num, content.rstrip()) + ) diff --git a/aeromancer/db/connect.py b/aeromancer/db/connect.py index 107d62d..245313b 100644 --- a/aeromancer/db/connect.py +++ b/aeromancer/db/connect.py @@ -1,6 +1,8 @@ import os +import re from sqlalchemy import create_engine +from sqlalchemy import event def get_url(): @@ -9,6 +11,18 @@ def get_url(): return "sqlite:///%s" % db_file_path +def _re_fn(expr, item): + "Registered as the regexp function with sqlite." + reg = re.compile(expr, re.I) + return reg.search(item) is not None + + def connect(): """Return a database engine""" - return create_engine(get_url()) + engine = create_engine(get_url()) + + @event.listens_for(engine, "begin") + def do_begin(conn): + conn.connection.create_function('regexp', 2, _re_fn) + + return engine diff --git a/aeromancer/project.py b/aeromancer/project.py index becd60f..90448e9 100644 --- a/aeromancer/project.py +++ b/aeromancer/project.py @@ -193,3 +193,17 @@ class ProjectManager(object): if name not in seen: self._remove_file_data(obj, reason='file no longer exists') self.session.flush() + + def grep(self, pattern): + """Given a pattern, search for lines in files in all projects that match it. + + Returns results of the query, including the four columns line + number, line content, filename, and project name. + + """ + query = self.session.query( + Line.number, Line.content, File.name, Project.name, + ).join(File, Project).filter( + Line.content.op('regexp')(pattern) + ) + return query.yield_per(20).all() diff --git a/setup.cfg b/setup.cfg index 3ab1ea0..01efc62 100644 --- a/setup.cfg +++ b/setup.cfg @@ -61,6 +61,7 @@ aeromancer.cli = requirements uses = aeromancer.requirements.cli:Uses oslo list = aeromancer.oslo.cli:List oslo uses = aeromancer.oslo.cli:Uses + grep = aeromancer.cli.grep:Grep aeromancer.filehandler = requirements = aeromancer.requirements.handler:RequirementsHandler