pydoit / doit

CLI task management & automation tool
http://pydoit.org
MIT License
1.87k stars 175 forks source link

Clean action return TaskFailed does not result in non-zero exit code #356

Open arichiardi opened 4 years ago

arichiardi commented 4 years ago

He there! :wave:

Not sure this is a bug or a feature request or expected but...I have the following dodo.py

DOIT_CONFIG = {
    "minversion": "0.32.0",
}

import subprocess
from subprocess import Popen, PIPE, STDOUT
import doit

def clean_with_non_zero(task):
    cmd = ["ls", "foo"]
    try:
        subprocess.run(cmd, shell=False, check=True, universal_newlines=True)
        return True
    except subprocess.CalledProcessError as e:
        return doit.exceptions.TaskFailed(e)

def task_fail():
    """Test a doit bug."""
    return {
        "actions": [clean_with_non_zero],
        "clean": [clean_with_non_zero],
        "verbosity": 2
    }

Please include a minimal dodo.py that reproduces the problem. If relevant also include the command line used to invoke doit.

When I run this I correctly see the exit code:

$ doit fail
.  fail
ls: cannot access 'foo': No such file or directory
TaskFailed - taskid:fail
Command '['ls', 'foo']' returned non-zero exit status 2.

$ echo $?
1

But in the following, I instead see a 0:

$ doit clean fail
fail - executing 'Python: function clean_with_non_zero'
ls: cannot access 'foo': No such file or directory
TaskFailed
Command '['ls', 'foo']' returned non-zero exit status 2.
$ echo $?
0

Environment

  1. OS: linux
  2. python version: Python 3.6.10
  3. doit version: 0.32.0

I have also check the source code and it seems that while this line sets the result, this other one in clean does not.

I am also wondering if this is designed to be this way, in which case I will try to explain our use case and why we would like to see a negative exit code there :smile:

As usual, thank you! The code is very readable and so far doit has been very nice to use!

Fund with Polar

schettino72 commented 4 years ago

It's a bug. It seems the exit code was never handled by "clean" command.

arichiardi commented 4 years ago

Any hint on an entry point for starting to have a look at this? I am pretty new to the code base...

schettino72 commented 4 years ago

1) tasks.py: Task.clean() should return the result of the action. 2) then on cmd_clean.py make sure you get & propagate that value

That's all, really simple. But please add unit-tests.