Skip to content

Commit

Permalink
Add a --run option in the create-project management command #37
Browse files Browse the repository at this point in the history
Signed-off-by: Thomas Druez <tdruez@nexb.com>
  • Loading branch information
tdruez committed Nov 5, 2020
1 parent fc283e4 commit 8419b03
Show file tree
Hide file tree
Showing 5 changed files with 56 additions and 16 deletions.
2 changes: 2 additions & 0 deletions docs/scanpipe-command-line.rst
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,8 @@ Optional arguments:

- ``--input INPUTS`` Input file locations to copy in the :guilabel:`input/` workspace directory.

- ``--run`` Start running the pipelines right after project creation.

.. warning::
The pipelines are added and will be running in the order of the provided options.

Expand Down
10 changes: 6 additions & 4 deletions docs/scanpipe-tutorial-1.rst
Original file line number Diff line number Diff line change
Expand Up @@ -72,8 +72,10 @@ Step-by-step
.. note::
The ``inputs`` and ``pipelines`` can be provided directly at once when
calling the ``create-project`` command.
For example, this command will create a project named ``p2``, copy our test
docker image to the project's inputs, and add the docker pipeline in one
operation::
A ``run`` option is also available to start the pipeline execution right
after the project creation.
For example, the following command will create a project named ``p2``,
copy the test docker image to the project's inputs, add the docker pipeline,
and execute the pipeline run in one operation::

$ scanpipe create-project p2 --input ~/30-alpine-nickolashkraus-staticbox-latest.tar --pipeline scanpipe/pipelines/docker.py
$ scanpipe create-project p2 --input ~/30-alpine-nickolashkraus-staticbox-latest.tar --pipeline scanpipe/pipelines/docker.py --run
13 changes: 13 additions & 0 deletions scanpipe/management/commands/create-project.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@

from django.core.exceptions import ValidationError
from django.core.management import CommandError
from django.core.management import call_command
from django.core.management.base import BaseCommand

from scanpipe.management.commands import copy_inputs
Expand Down Expand Up @@ -52,11 +53,17 @@ def add_arguments(self, parser):
default=list(),
help="Input file locations to copy in the input/ work directory.",
)
parser.add_argument(
"--run",
action="store_true",
help="Start running the pipelines right after project creation.",
)

def handle(self, *args, **options):
name = options["name"]
pipelines = options["pipelines"]
inputs = options["inputs"]
run = options["run"]

project = Project(name=name)
try:
Expand All @@ -68,6 +75,9 @@ def handle(self, *args, **options):
validate_pipelines(pipelines)
validate_inputs(inputs)

if run and not pipelines:
raise CommandError("The --run option requires one or more pipelines.")

project.save()
msg = f"Project {name} created with work directory {project.work_directory}"
self.stdout.write(self.style.SUCCESS(msg))
Expand All @@ -76,3 +86,6 @@ def handle(self, *args, **options):
project.add_pipeline(pipeline_location)

copy_inputs(inputs, project.input_path)

if run:
call_command("run", project=project, stderr=self.stderr, stdout=self.stdout)
4 changes: 1 addition & 3 deletions scanpipe/management/commands/run.py
Original file line number Diff line number Diff line change
Expand Up @@ -53,9 +53,7 @@ def handle(self, *args, **options):
if not run:
raise CommandError(f"No pipelines to {action} on project {self.project}")

msg = f"Pipeline {run.pipeline} {action} in progress..."
self.stdout.write(msg)

self.stdout.write(f"Pipeline {run.pipeline} {action} in progress...")
getattr(run, task_function)()

run.refresh_from_db()
Expand Down
43 changes: 34 additions & 9 deletions scanpipe/tests/test_commands.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,17 @@
from scanpipe.models import Project


def task_success(run):
run.task_exitcode = 0
run.save()


def task_failure(run):
run.task_output = "Error log"
run.task_exitcode = 1
run.save()


class ScanPipeManagementCommandTest(TestCase):
pipeline_location = "scanpipe/pipelines/docker.py"

Expand Down Expand Up @@ -111,6 +122,29 @@ def test_scanpipe_management_command_create_project_inputs(self):
expected = sorted(["test_commands.py", "test_models.py"])
self.assertEqual(expected, sorted(project.input_files))

def test_scanpipe_management_command_create_project_run(self):
out = StringIO()

options = ["--run"]
expected = "The --run option requires one or more pipelines."
with self.assertRaisesMessage(CommandError, expected):
call_command("create-project", "my_project", *options)

pipeline = "scanpipe/pipelines/scan_inventory.py"
options = [
"--pipeline",
pipeline,
"--run",
]

out = StringIO()
with mock.patch("scanpipe.models.Run.run_pipeline_task_async", task_success):
call_command("create-project", "my_project", *options, stdout=out)

self.assertIn("Project my_project created", out.getvalue())
self.assertIn(f"Pipeline {pipeline} run in progress...", out.getvalue())
self.assertIn("successfully executed on project my_project", out.getvalue())

def test_scanpipe_management_command_add_input(self):
out = StringIO()

Expand Down Expand Up @@ -202,10 +236,6 @@ def test_scanpipe_management_command_run(self):

project.add_pipeline(self.pipeline_location)

def task_success(run):
run.task_exitcode = 0
run.save()

out = StringIO()
with mock.patch("scanpipe.models.Run.run_pipeline_task_async", task_success):
call_command("run", *options, stdout=out)
Expand All @@ -214,11 +244,6 @@ def task_success(run):
expected = "successfully executed on project my_project"
self.assertIn(expected, out.getvalue())

def task_failure(run):
run.task_output = "Error log"
run.task_exitcode = 1
run.save()

err = StringIO()
project.add_pipeline(self.pipeline_location)
with mock.patch("scanpipe.models.Run.run_pipeline_task_async", task_failure):
Expand Down

0 comments on commit 8419b03

Please sign in to comment.