package dk.teachus.tools.actions;

import java.io.File;
import java.io.IOException;
import java.util.Arrays;

import org.apache.commons.io.FileUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

/**
 * Git client using local commands
 */
public class GitCommandScmClient implements ScmClient {
	private static final Log log = LogFactory.getLog(GitCommandScmClient.class);

	private String remoteGitRepository;
	private String committerName;
	private String committerEmail;

	public GitCommandScmClient(String remoteGitRepository, String committerName, String committerEmail) {
		this.remoteGitRepository = remoteGitRepository;
		this.committerName = committerName;
		this.committerEmail = committerEmail;
	}

	public void checkout(File projectDirectory, String version) {
		if (projectDirectory.exists()) {
			try {
				FileUtils.deleteDirectory(projectDirectory);
			} catch (IOException e) {
				throw new RuntimeException(e);
			}
		}
		
		executeGitCommand(null, new String[] {"clone", remoteGitRepository, projectDirectory.getAbsolutePath()});
		
		executeGitCommand(projectDirectory, new String[] {"config", "user.name", committerName});
		executeGitCommand(projectDirectory, new String[] {"config", "user.email", committerEmail});
		
		if (version != null) {
			executeGitCommand(projectDirectory, new String[] {"checkout", version});
		}
	}

	public void commit(File projectDirectory, String message, File[] files) {
		for (File file : files) {
			String relativePath = file.getAbsolutePath().replace(projectDirectory.getAbsolutePath(), "");
			if (relativePath.startsWith(System.getProperty("file.separator"))) {
				relativePath = relativePath.substring(1);
			}
			executeGitCommand(projectDirectory, new String[] {"add", relativePath});
		}
		
		executeGitCommand(projectDirectory, new String[]{"commit", "-m", message});
		
		executeGitCommand(projectDirectory, new String[]{"push"});
	}

	public void tag(File projectDirectory, String version) {
		executeGitCommand(projectDirectory, new String[]{"tag", version});
		
		executeGitCommand(projectDirectory, new String[]{"push", "--tags"});
	}
	
	private void executeGitCommand(File projectDirectory, String[] params) {
		try {
			String gitCommand[] = new String[params.length + 1];
			gitCommand[0] = "git";
			int i = 1;
			for (String param : params) {
				gitCommand[i++] = param;
			}
			if (log.isDebugEnabled()) {
				log.debug("Executing git command: '"+Arrays.toString(gitCommand)+"'");
			}
			
			Process process = Runtime.getRuntime().exec(gitCommand, null, projectDirectory);
			if (process.waitFor() != 0) {
				throw new IOException("Git command didn't finish properly: "+process.exitValue());
			}
		} catch (IOException e) {
			throw new RuntimeException(e);
		} catch (InterruptedException e) {
			throw new RuntimeException(e);
		}
	}

}

package dk.teachus.tools.actions;

import java.io.BufferedReader;
import java.io.File;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.Arrays;

import org.apache.commons.io.FileUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

/**
 * Git client using local commands
 */
public class GitCommandScmClient implements ScmClient {
	private static final Log log = LogFactory.getLog(GitCommandScmClient.class);

	private String remoteGitRepository;
	private String committerName;
	private String committerEmail;

	public GitCommandScmClient(String remoteGitRepository, String committerName, String committerEmail) {
		this.remoteGitRepository = remoteGitRepository;
		this.committerName = committerName;
		this.committerEmail = committerEmail;
	}

	public void checkout(File projectDirectory, String version) {
		if (projectDirectory.exists()) {
			try {
				FileUtils.deleteDirectory(projectDirectory);
			} catch (IOException e) {
				throw new RuntimeException(e);
			}
		}
		
		executeGitCommand(null, new String[] {"clone", remoteGitRepository, projectDirectory.getAbsolutePath()});
		
		executeGitCommand(projectDirectory, new String[] {"config", "user.name", committerName});
		executeGitCommand(projectDirectory, new String[] {"config", "user.email", committerEmail});
		
		if (version != null) {
			executeGitCommand(projectDirectory, new String[] {"checkout", version});
		}
	}

	public void commit(File projectDirectory, String message, File[] files) {
		for (File file : files) {
			String relativePath = file.getAbsolutePath().replace(projectDirectory.getAbsolutePath(), "");
			if (relativePath.startsWith(System.getProperty("file.separator"))) {
				relativePath = relativePath.substring(1);
			}
			executeGitCommand(projectDirectory, new String[] {"add", relativePath});
		}
		
		executeGitCommand(projectDirectory, new String[]{"commit", "-m", message});
		
		executeGitCommand(projectDirectory, new String[]{"push"});
	}

	public void tag(File projectDirectory, String version) {
		executeGitCommand(projectDirectory, new String[]{"tag", version});
		
		executeGitCommand(projectDirectory, new String[]{"push", "--tags"});
	}
	
	private void executeGitCommand(File projectDirectory, String[] params) {
		try {
			String gitCommand[] = new String[params.length + 1];
			gitCommand[0] = "git";
			int i = 1;
			for (String param : params) {
				gitCommand[i++] = param;
			}
			if (log.isDebugEnabled()) {
				log.debug("Executing git command: '"+Arrays.toString(gitCommand)+"'");
			}
			
			Process process = Runtime.getRuntime().exec(gitCommand, null, projectDirectory);
			
			BufferedReader errorStream = new BufferedReader(new InputStreamReader(process.getErrorStream()));
			String line = null;
			while ((line = errorStream.readLine()) != null) {
				System.out.println(line);
			}
			if (process.waitFor() != 0) {
				throw new IOException("Git command didn't finish properly: "+process.exitValue());
			}
		} catch (IOException e) {
			throw new RuntimeException(e);
		} catch (InterruptedException e) {
			throw new RuntimeException(e);
		}
	}

}

Print errors generated by the git command, for better debugging possibilities.