Coverage Report - liquibase.change.core.ExecuteShellCommandChange
 
Classes in this File Line Coverage Branch Coverage Complexity
ExecuteShellCommandChange
9%
3/31
0%
0/14
2.167
ExecuteShellCommandChange$1
0%
0/23
0%
0/2
2.167
 
 1  
 package liquibase.change.core;
 2  
 
 3  
 import liquibase.change.AbstractChange;
 4  
 import liquibase.change.ChangeMetaData;
 5  
 import liquibase.database.Database;
 6  
 import liquibase.exception.UnexpectedLiquibaseException;
 7  
 import liquibase.exception.ValidationErrors;
 8  
 import liquibase.exception.Warnings;
 9  
 import liquibase.executor.Executor;
 10  
 import liquibase.executor.ExecutorService;
 11  
 import liquibase.executor.LoggingExecutor;
 12  
 import liquibase.logging.LogFactory;
 13  
 import liquibase.sql.Sql;
 14  
 import liquibase.statement.SqlStatement;
 15  
 import liquibase.statement.core.CommentStatement;
 16  
 import liquibase.statement.core.RuntimeStatement;
 17  
 import liquibase.util.StreamUtil;
 18  
 import liquibase.util.StringUtils;
 19  
 
 20  
 import java.io.ByteArrayOutputStream;
 21  
 import java.io.IOException;
 22  
 import java.util.ArrayList;
 23  
 import java.util.List;
 24  
 
 25  
 /**
 26  
  * Executes a given shell executable.
 27  
  */
 28  0
 public class ExecuteShellCommandChange extends AbstractChange {
 29  
 
 30  
     private String executable;
 31  
     private List<String> os;
 32  10
     private List<String> args = new ArrayList<String>();
 33  
 
 34  
     public ExecuteShellCommandChange() {
 35  10
         super("executeCommand", "Execute Shell Command", ChangeMetaData.PRIORITY_DEFAULT);
 36  10
     }
 37  
 
 38  
     public String getExecutable() {
 39  0
         return executable;
 40  
     }
 41  
 
 42  
     public void setExecutable(String executable) {
 43  0
         this.executable = executable;
 44  0
     }
 45  
 
 46  
     public void addArg(String arg) {
 47  0
         this.args.add(arg);
 48  0
     }
 49  
 
 50  
     public void setOs(String os) {
 51  0
         this.os = StringUtils.splitAndTrim(os, ",");
 52  0
     }
 53  
 
 54  
     public List<String> getOs() {
 55  0
         return os;
 56  
     }
 57  
 
 58  
     @Override
 59  
     public ValidationErrors validate(Database database) {
 60  0
         return new ValidationErrors();
 61  
     }
 62  
 
 63  
     @Override
 64  
     public Warnings warn(Database database) {
 65  0
         return new Warnings();
 66  
     }
 67  
 
 68  
     public SqlStatement[] generateStatements(final Database database) {
 69  0
         boolean shouldRun = true;
 70  0
         if (os != null && os.size() > 0) {
 71  0
             String currentOS = System.getProperty("os.name");
 72  0
             if (!os.contains(currentOS)) {
 73  0
                 shouldRun = false;
 74  0
                 LogFactory.getLogger().info("Not executing on os " + currentOS + " when " + os + " was specified");
 75  
             }
 76  
         }
 77  
 
 78  
         // check if running under not-executed mode (logging output)
 79  0
         boolean nonExecutedMode = false;
 80  0
         Executor executor = ExecutorService.getInstance().getExecutor(database);
 81  0
         if (executor instanceof LoggingExecutor) {
 82  0
             nonExecutedMode = true;
 83  
         }
 84  
 
 85  0
         if (shouldRun && !nonExecutedMode) {
 86  
 
 87  0
             return new SqlStatement[] { new RuntimeStatement() {
 88  
 
 89  
                 @Override
 90  
                 public Sql[] generate(Database database) {
 91  0
                     List<String> commandArray = new ArrayList<String>();
 92  0
                     commandArray.add(executable);
 93  0
                     commandArray.addAll(args);
 94  
 
 95  
                     try {
 96  0
                         ProcessBuilder pb = new ProcessBuilder(commandArray);
 97  0
                         pb.redirectErrorStream(true);
 98  0
                         Process p = pb.start();
 99  0
                         int returnCode = 0;
 100  
                         try {
 101  0
                             returnCode = p.waitFor();
 102  0
                         } catch (InterruptedException e) {
 103  
                             ;
 104  0
                         }
 105  
 
 106  0
                         ByteArrayOutputStream errorStream = new ByteArrayOutputStream();
 107  0
                         ByteArrayOutputStream inputStream = new ByteArrayOutputStream();
 108  0
                         StreamUtil.copy(p.getErrorStream(), errorStream);
 109  0
                         StreamUtil.copy(p.getInputStream(), inputStream);
 110  
 
 111  0
                         LogFactory.getLogger().severe(errorStream.toString());
 112  0
                         LogFactory.getLogger().info(inputStream.toString());
 113  
 
 114  0
                         if (returnCode != 0) {
 115  0
                             throw new RuntimeException(getCommandString() + " returned an code of " + returnCode);
 116  
                         }
 117  0
                     } catch (IOException e) {
 118  0
                         throw new UnexpectedLiquibaseException("Error executing command: " + e);
 119  0
                     }
 120  
 
 121  0
                     return null;
 122  
                 }
 123  
             } };
 124  
         }
 125  
 
 126  0
         if (nonExecutedMode) {
 127  0
             return new SqlStatement[] { new CommentStatement(getCommandString()) };
 128  
         }
 129  
 
 130  0
         return new SqlStatement[0];
 131  
     }
 132  
 
 133  
     public String getConfirmationMessage() {
 134  0
         return "Shell command '" + getCommandString() + "' executed";
 135  
     }
 136  
 
 137  
     private String getCommandString() {
 138  0
         return executable + " " + StringUtils.join(args, " ");
 139  
     }
 140  
 }