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
|
||||||
from aeromancer import project_filter
|
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"""
|
"""Search the contents of files"""
|
||||||
|
|
||||||
log = logging.getLogger(__name__)
|
log = logging.getLogger(__name__)
|
||||||
|
|
||||||
def get_parser(self, prog_name):
|
def get_parser(self, prog_name):
|
||||||
parser = super(Grep, self).get_parser(prog_name)
|
parser = super(Grep, self).get_parser(prog_name)
|
||||||
project_filter.ProjectFilter.add_arguments(parser)
|
|
||||||
parser.add_argument('pattern',
|
parser.add_argument('pattern',
|
||||||
action='store',
|
action='store',
|
||||||
help='regular expression',
|
help='regular expression',
|
||||||
)
|
)
|
||||||
return parser
|
return parser
|
||||||
|
|
||||||
def take_action(self, parsed_args):
|
def _get_command(self, parsed_args):
|
||||||
session = self.app.get_db_session()
|
return ['git', 'grep', parsed_args.pattern]
|
||||||
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)
|
|
||||||
|
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._remove_file_data(obj, reason='file no longer exists')
|
||||||
self.session.flush()
|
self.session.flush()
|
||||||
|
|
||||||
def grep(self, pattern, prj_filter):
|
def run(self, command, prj_filter):
|
||||||
"""Given a pattern, search for lines in files in all projects that match it.
|
"""Given a command, run it for all projects.
|
||||||
|
|
||||||
Returns results of the query, including the four columns line
|
Returns sequence of tuples containing project objects, the
|
||||||
number, line content, filename, and project name.
|
output, and the errors from the command.
|
||||||
|
|
||||||
"""
|
"""
|
||||||
# TODO: Would it be more efficient to register the regexp
|
# TODO: Would it be more efficient to register the regexp
|
||||||
@ -212,13 +212,11 @@ class ProjectManager(object):
|
|||||||
#return query.yield_per(20).all()
|
#return query.yield_per(20).all()
|
||||||
for project in query.all():
|
for project in query.all():
|
||||||
cmd = subprocess.Popen(
|
cmd = subprocess.Popen(
|
||||||
['git', 'grep', pattern],
|
command,
|
||||||
stdout=subprocess.PIPE,
|
stdout=subprocess.PIPE,
|
||||||
|
stderr=subprocess.PIPE,
|
||||||
cwd=project.path,
|
cwd=project.path,
|
||||||
env={'PAGER': ''},
|
env={'PAGER': ''}, # override pager for git commands
|
||||||
)
|
)
|
||||||
out, err = cmd.communicate()
|
out, err = cmd.communicate()
|
||||||
if not out:
|
yield (project, out, err)
|
||||||
continue
|
|
||||||
for line in out.decode('utf-8').splitlines():
|
|
||||||
yield project.name + line
|
|
||||||
|
@ -62,6 +62,7 @@ aeromancer.cli =
|
|||||||
oslo list = aeromancer.oslo.cli:List
|
oslo list = aeromancer.oslo.cli:List
|
||||||
oslo uses = aeromancer.oslo.cli:Uses
|
oslo uses = aeromancer.oslo.cli:Uses
|
||||||
grep = aeromancer.cli.grep:Grep
|
grep = aeromancer.cli.grep:Grep
|
||||||
|
run = aeromancer.cli.run:Run
|
||||||
|
|
||||||
aeromancer.filehandler =
|
aeromancer.filehandler =
|
||||||
requirements = aeromancer.requirements.handler:RequirementsHandler
|
requirements = aeromancer.requirements.handler:RequirementsHandler
|
||||||
|
Loading…
x
Reference in New Issue
Block a user