Add "run" command and refactor grep
Add a run command for running shell commands in projects and refactor grep to use the same base class.
This commit is contained in:
parent
afe9eafba5
commit
820caf5555
@ -6,26 +6,21 @@ import os
|
||||
from aeromancer import project
|
||||
from aeromancer import project_filter
|
||||
|
||||
from cliff.command import Command
|
||||
from aeromancer.cli.run import ProjectShellCommandBase
|
||||
|
||||
|
||||
class Grep(Command):
|
||||
class Grep(ProjectShellCommandBase):
|
||||
"""Search the contents of files"""
|
||||
|
||||
log = logging.getLogger(__name__)
|
||||
|
||||
def get_parser(self, prog_name):
|
||||
parser = super(Grep, self).get_parser(prog_name)
|
||||
project_filter.ProjectFilter.add_arguments(parser)
|
||||
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)
|
||||
prj_filt = project_filter.ProjectFilter.from_parsed_args(parsed_args)
|
||||
for l in pm.grep(parsed_args.pattern, prj_filt):
|
||||
print(l)
|
||||
def _get_command(self, parsed_args):
|
||||
return ['git', 'grep', parsed_args.pattern]
|
||||
|
68
aeromancer/cli/run.py
Normal file
68
aeromancer/cli/run.py
Normal file
@ -0,0 +1,68 @@
|
||||
from __future__ import print_function
|
||||
|
||||
import logging
|
||||
import os
|
||||
import shlex
|
||||
|
||||
from aeromancer import project
|
||||
from aeromancer import project_filter
|
||||
|
||||
from cliff.command import Command
|
||||
|
||||
|
||||
class ProjectShellCommandBase(Command):
|
||||
"""Run a command for each project"""
|
||||
|
||||
log = logging.getLogger(__name__)
|
||||
|
||||
DEFAULT_SEP = ''
|
||||
|
||||
def get_parser(self, prog_name):
|
||||
parser = super(ProjectShellCommandBase, self).get_parser(prog_name)
|
||||
project_filter.ProjectFilter.add_arguments(parser)
|
||||
parser.add_argument(
|
||||
'--sep',
|
||||
action='store',
|
||||
default=self.DEFAULT_SEP,
|
||||
help=('separator between project name and command output, '
|
||||
'defaults to %(default)r'),
|
||||
)
|
||||
return parser
|
||||
|
||||
def _show_text_output(self, parsed_args, project, out):
|
||||
for line in out.decode('utf-8').splitlines():
|
||||
print(project.name + parsed_args.sep + line)
|
||||
|
||||
def _get_command(self, parsed_args):
|
||||
raise NotImplementedError()
|
||||
|
||||
def _show_output(self, parsed_args, proj_obj, out, err):
|
||||
self._show_text_output(parsed_args, proj_obj, err or out)
|
||||
|
||||
def take_action(self, parsed_args):
|
||||
session = self.app.get_db_session()
|
||||
pm = project.ProjectManager(session)
|
||||
prj_filt = project_filter.ProjectFilter.from_parsed_args(parsed_args)
|
||||
command = self._get_command(parsed_args)
|
||||
results = pm.run(command, prj_filt)
|
||||
for proj_obj, out, err in results:
|
||||
self._show_output(parsed_args, proj_obj, out, err)
|
||||
|
||||
|
||||
class Run(ProjectShellCommandBase):
|
||||
"""Run a command for each project"""
|
||||
|
||||
log = logging.getLogger(__name__)
|
||||
|
||||
DEFAULT_SEP = ':'
|
||||
|
||||
def get_parser(self, prog_name):
|
||||
parser = super(Run, self).get_parser(prog_name)
|
||||
parser.add_argument('command',
|
||||
action='store',
|
||||
help='the command to run, probably quoted',
|
||||
)
|
||||
return parser
|
||||
|
||||
def _get_command(self, parsed_args):
|
||||
return shlex.shlex(parsed_args.command)
|
@ -194,11 +194,11 @@ class ProjectManager(object):
|
||||
self._remove_file_data(obj, reason='file no longer exists')
|
||||
self.session.flush()
|
||||
|
||||
def grep(self, pattern, prj_filter):
|
||||
"""Given a pattern, search for lines in files in all projects that match it.
|
||||
def run(self, command, prj_filter):
|
||||
"""Given a command, run it for all projects.
|
||||
|
||||
Returns results of the query, including the four columns line
|
||||
number, line content, filename, and project name.
|
||||
Returns sequence of tuples containing project objects, the
|
||||
output, and the errors from the command.
|
||||
|
||||
"""
|
||||
# TODO: Would it be more efficient to register the regexp
|
||||
@ -212,13 +212,11 @@ class ProjectManager(object):
|
||||
#return query.yield_per(20).all()
|
||||
for project in query.all():
|
||||
cmd = subprocess.Popen(
|
||||
['git', 'grep', pattern],
|
||||
command,
|
||||
stdout=subprocess.PIPE,
|
||||
stderr=subprocess.PIPE,
|
||||
cwd=project.path,
|
||||
env={'PAGER': ''},
|
||||
env={'PAGER': ''}, # override pager for git commands
|
||||
)
|
||||
out, err = cmd.communicate()
|
||||
if not out:
|
||||
continue
|
||||
for line in out.decode('utf-8').splitlines():
|
||||
yield project.name + line
|
||||
yield (project, out, err)
|
||||
|
Loading…
x
Reference in New Issue
Block a user