package org.vaadin.mideaas.model; import java.io.File; import java.io.IOException; import java.util.regex.Matcher; import java.util.regex.Pattern; import org.codehaus.plexus.util.FileUtils; import org.eclipse.jgit.api.CloneCommand; import org.eclipse.jgit.api.CommitCommand; import org.eclipse.jgit.api.Git; import org.eclipse.jgit.api.PushCommand; import org.eclipse.jgit.api.errors.GitAPIException; import org.eclipse.jgit.api.errors.InvalidRemoteException; import org.eclipse.jgit.api.errors.JGitInternalException; import org.eclipse.jgit.api.errors.TransportException; import org.eclipse.jgit.lib.Repository; import org.eclipse.jgit.lib.StoredConfig; import org.eclipse.jgit.revwalk.RevCommit; import org.eclipse.jgit.storage.file.FileRepository; import org.eclipse.jgit.transport.CredentialsProvider; import org.eclipse.jgit.transport.PushResult; import org.eclipse.jgit.transport.UsernamePasswordCredentialsProvider; import com.vaadin.ui.Notification; /** * The Class GitRepository. */ public class GitRepository { /** The git. */ private final Git git; /** The Constant gitUrlPattern. */ private static final Pattern gitUrlPattern = Pattern.compile(".*/([^/.]+).git"); /** * Inits new gitrepository to the directory given * * @param dir of new repository * @return the git repository * @throws IOException Signals that an I/O exception has occurred. */ public static GitRepository initAt(File dir) throws IOException { Repository newRepo = new FileRepository(new File(dir, ".git")); newRepo.create(); return new GitRepository(new Git(newRepo)); } /** * Inits new gitrepository from directory. * * @param dir the dir * @return the git repository * @throws IOException Signals that an I/O exception has occurred. */ public static GitRepository fromExistingGitDir(File dir) throws IOException { //tries to find .git file from directory File gitDir = new File(dir, ".git"); Git repo = Git.open(gitDir); return new GitRepository(repo); } public static GitRepository cloneFrom(String gitUrl, File destDir) { try { deleteContent(destDir); CloneCommand command = Git.cloneRepository(); command.setURI(gitUrl); command.setDirectory(destDir); return new GitRepository(command.call()); } catch (GitAPIException e) { // TODO Auto-generated catch block e.printStackTrace(); } return null; // XXX? } /** * Delete content. * * @param dir the dir */ private static void deleteContent(File dir) { File[] files; try { files = dir.listFiles(); while(files.length>0){ FileUtils.deleteDirectory(files[0]); files = dir.listFiles(); } } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } /** * Default project name from git url. * * @param gitUrl the git url * @return the string */ public static String defaultProjectNameFromGitUrl(String gitUrl) { Matcher matcher = gitUrlPattern.matcher(gitUrl); if (!matcher.matches()) { throw new IllegalArgumentException("Not a proper git url(?): "+gitUrl); } return matcher.group(1); } /** * Instantiates a new git repository. * * @param git the git */ private GitRepository(Git git) { this.git = git; } /** * Adds all the source files to git. * * @throws GitAPIException the git api exception */ public void addSourceFilesToGit() throws GitAPIException { git.add().addFilepattern("src/main/java").call(); git.add().addFilepattern("src/main/resources").call(); git.add().addFilepattern("src/main/webapp/WEB-INF").call(); git.add().addFilepattern("src/main/webapp/META-INF").call(); git.add().addFilepattern("pom.xml").call(); } /** * Commit all. * * @param msg the msg * @throws GitAPIException the git api exception */ public void commitAll(String msg) throws GitAPIException { CommitCommand command = git.commit().setMessage(msg).setAll(true); RevCommit result = command.call(); String message=result.getFullMessage(); if (message.length()>0){ Notification.show("Commit ok, message: " + message); }else{ Notification.show("Commit ok, no commit message :( ?"); } } public void pushAll(String userName, String password, String remoteName) throws GitAPIException { // credentials CredentialsProvider credentials = null; credentials = new UsernamePasswordCredentialsProvider(userName, password); try{ PushCommand command = git.push().setRemote(remoteName); command.setCredentialsProvider(credentials); Iterable<PushResult> results = command.call(); int updates = 0; for (PushResult result:results){ updates += result.getRemoteUpdates().size(); } if (updates==0){ Notification.show("No updates pushed. Something maybe failed?", Notification.Type.WARNING_MESSAGE); }else if (updates==1){ Notification.show("Update pushed."); }else{ Notification.show(updates + " updates pushed."); } }catch(JGitInternalException e){ Notification.show("Push failed. Did you remember to commit first? " + e.getMessage(), Notification.Type.ERROR_MESSAGE); }catch(InvalidRemoteException e){ Notification.show("Push failed: " + e.getMessage(), Notification.Type.ERROR_MESSAGE); }catch(TransportException e){ Notification.show("Push failed: " + e.getMessage(), Notification.Type.ERROR_MESSAGE); } } public String getRemote(String name){ StoredConfig config = this.git.getRepository().getConfig(); String url = config.getString("remote", name, "url"); return url; } public boolean hasCommit(){ return !git.getRepository().getAllRefs().isEmpty(); } public void addRemote(String name, String url) { Repository repo = this.git.getRepository(); StoredConfig config = repo.getConfig(); config.setString("remote", name, "url", url); try { config.save(); Notification.show("Remote "+name+" set to: " + url); } catch (IOException e) { // TODO Auto-generated catch block Notification.show("Set origin failed."); e.printStackTrace(); } } }