package io.digdag.core.workflow;

import java.io.File;
import java.io.IOException;
import java.nio.file.Path;
import com.google.inject.Inject;
import com.google.common.base.Optional;
import io.digdag.spi.CommandExecutor;
import io.digdag.spi.TaskRequest;

public class MockCommandExecutor
    implements CommandExecutor
{
    @Inject
    public MockCommandExecutor()
    { }

    public Process start(Path projectPath, TaskRequest request, ProcessBuilder pb)
        throws IOException
    {
        return pb.start();
    }
}

@@ -38,148 +38,204 @@
 ort 
-java.io.File;%0Aimport java.io.IOException;%0Aimport java.nio.file.Path;%0Aimport com.google.inject.Inject;%0Aimport com.google.common.base.Optional
+com.fasterxml.jackson.databind.node.ObjectNode;%0Aimport com.google.common.base.Throwables;%0Aimport com.google.inject.Inject;%0Aimport io.digdag.spi.CommandExecutor;%0Aimport io.digdag.spi.CommandContext
 ;%0Aim
@@ -256,32 +256,31 @@
 .spi.Command
-Executor
+Request
 ;%0Aimport io.
@@ -290,27 +290,57 @@
 dag.spi.
-TaskRequest
+CommandStatus;%0Aimport java.io.IOException
 ;%0A%0Apubli
@@ -462,143 +462,1599 @@
     
-public Process start(Path projectPath, TaskRequest request, ProcessBuilder pb)%0A        throws IOException%0A    %7B%0A        return pb.start
+@Override%0A    public CommandStatus run(CommandContext context, CommandRequest request)%0A            throws IOException%0A    %7B%0A        final ProcessBuilder pb = new ProcessBuilder(request.getCommandLine());%0A        pb.directory(request.getWorkingDirectory().normalize().toAbsolutePath().toFile());%0A        pb.redirectErrorStream(true);%0A        pb.environment().putAll(request.getEnvironments());%0A%0A        // TODO set TZ environment variable%0A        final Process p = pb.start();%0A%0A        // Need waiting and blocking. Because the process is running on a single instance.%0A        // The command task could not be taken by other digdag-servers on other instances.%0A        try %7B%0A            p.waitFor();%0A        %7D%0A        catch (InterruptedException e) %7B%0A            throw Throwables.propagate(e);%0A        %7D%0A%0A        return new CommandStatus() %7B%0A            @Override%0A            public boolean isFinished()%0A            %7B%0A                return true;%0A            %7D%0A%0A            @Override%0A            public int getStatusCode()%0A            %7B%0A                return p.exitValue();%0A            %7D%0A%0A            @Override%0A            public String getIoDirectory()%0A            %7B%0A                return request.getIoDirectory().toString();%0A            %7D%0A%0A            @Override%0A            public ObjectNode toJson()%0A            %7B%0A                throw new UnsupportedOperationException();%0A            %7D%0A        %7D;%0A    %7D%0A%0A    @Override%0A    public CommandStatus poll(CommandContext context, ObjectNode previousStatusJson)%0A            throws IOException%0A    %7B%0A        throw new UnsupportedOperationException
 ();%0A

change workflow.MockCommandExecutor according to new SPI