r1622 - in isis-fish/trunk/src: main/java/fr/ifremer/isisfish/vcs test/java/fr/ifremer/isisfish/vcs
Author: chatellier Date: 2008-11-27 11:45:40 +0000 (Thu, 27 Nov 2008) New Revision: 1622 Modified: isis-fish/trunk/src/main/java/fr/ifremer/isisfish/vcs/AbstractVCS.java isis-fish/trunk/src/main/java/fr/ifremer/isisfish/vcs/VCS.java isis-fish/trunk/src/main/java/fr/ifremer/isisfish/vcs/VCSSVN.java isis-fish/trunk/src/test/java/fr/ifremer/isisfish/vcs/VCSSVNTest.java Log: Update SVN VCS, svnkit 1.2, add missing implementation Modified: isis-fish/trunk/src/main/java/fr/ifremer/isisfish/vcs/AbstractVCS.java =================================================================== --- isis-fish/trunk/src/main/java/fr/ifremer/isisfish/vcs/AbstractVCS.java 2008-11-27 11:28:02 UTC (rev 1621) +++ isis-fish/trunk/src/main/java/fr/ifremer/isisfish/vcs/AbstractVCS.java 2008-11-27 11:45:40 UTC (rev 1622) @@ -1,33 +1,32 @@ -/* *##% - * Copyright (C) 2002-2008 Code Lutin, Benjamin Poussin - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, - * USA. - *##%*/ +/* *##% GeSi + * Copyright (C) 2008 CodeLutin + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Lesser Public License for more details. + * + * You should have received a copy of the GNU General Lesser Public + * License along with this program. If not, see + * <http://www.gnu.org/licenses/lgpl-3.0.html>. ##%*/ package fr.ifremer.isisfish.vcs; - import java.io.File; import java.util.HashSet; import java.util.Set; + import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; /** - * + * Abstract VCS implementation. + * * @author poussin * @version $Revision$ * @@ -36,9 +35,9 @@ */ public abstract class AbstractVCS implements VCS { - /** to use log facility, just put in your code: log.info(\"...\"); */ - static private Log log = LogFactory.getLog(AbstractVCS.class); - + /** Class logger */ + private static Log log = LogFactory.getLog(AbstractVCS.class); + protected Set<VetoableActionListener> listeners = new HashSet<VetoableActionListener>(); protected File localRepository; protected String protocol; @@ -48,10 +47,9 @@ protected String login; protected String password; protected boolean writeable = true; - - public AbstractVCS(File localRepository, - String protocol, String host, String path, - File sshKeyFile, String login, String password) { + + public AbstractVCS(File localRepository, String protocol, String host, + String path, File sshKeyFile, String login, String password) { this.localRepository = localRepository; this.protocol = protocol; this.host = host; @@ -73,12 +71,12 @@ this.writeable = value; } - protected boolean fireAction(VCSActionEvent e, File ... files) { + protected boolean fireAction(VCSActionEvent e, File... files) { boolean result = true; if (listeners.size() > 0) { // on evite la concurrence - VetoableActionListener[] ls = - listeners.toArray(new VetoableActionListener[listeners.size()]); + VetoableActionListener[] ls = listeners + .toArray(new VetoableActionListener[listeners.size()]); for (VetoableActionListener l : ls) { result = result && l.canDoAction(this, e, files); if (!result) { @@ -93,7 +91,7 @@ } return result; } - + public File getLocalRepository() { return localRepository; } @@ -101,16 +99,16 @@ public void setLocalRepository(File localRepository) { this.localRepository = localRepository; } - + public String getProtocol() { return protocol; } /** - * checkProtocol is automaticaly done - * @param path + * checkProtocol is automatically done + * @param protocol */ - public void setProtocol(String protocol) throws VCSException { + public void setProtocol(String protocol) throws VCSException { this.protocol = protocol; checkProtocol(); } @@ -120,10 +118,10 @@ } /** - * checkProtocol is automaticaly done - * @param path + * checkProtocol is automatically done + * @param host */ - public void setHost(String host) throws VCSException { + public void setHost(String host) throws VCSException { this.host = host; checkProtocol(); } @@ -133,7 +131,7 @@ } /** - * checkProtocol is automaticaly done + * checkProtocol is automatically done * @param path */ public void setPath(String path) throws VCSException { @@ -154,10 +152,10 @@ } /** - * checkProtocol is automaticaly done - * @param path + * checkProtocol is automatically done + * @param login */ - public void setLogin(String login) throws VCSException { + public void setLogin(String login) throws VCSException { this.login = login; checkProtocol(); } @@ -176,11 +174,12 @@ public boolean isVersionnableAbleFile(File file) { String filename = file.getName(); - return !".svn".equals(filename) && !"CVS".equals(filename) && - !filename.endsWith("~") && - // si le fichier n'appartient pas a loca repository, + return !".svn".equals(filename) && !"CVS".equals(filename) + && !filename.endsWith("~") && + // si le fichier n'appartient pas a local repository, // il ne pourra pas etre versionne - file.getAbsolutePath().startsWith(getLocalRepository().getAbsolutePath()); + file.getAbsolutePath().startsWith( + getLocalRepository().getAbsolutePath()); } } Modified: isis-fish/trunk/src/main/java/fr/ifremer/isisfish/vcs/VCS.java =================================================================== --- isis-fish/trunk/src/main/java/fr/ifremer/isisfish/vcs/VCS.java 2008-11-27 11:28:02 UTC (rev 1621) +++ isis-fish/trunk/src/main/java/fr/ifremer/isisfish/vcs/VCS.java 2008-11-27 11:45:40 UTC (rev 1622) @@ -1,20 +1,19 @@ -/* - * Copyright (C) 2002-2008 Code Lutin, Benjamin Poussin - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, - * USA. +/* *##% GeSi + * Copyright (C) 2008 CodeLutin + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Lesser Public License for more details. + * + * You should have received a copy of the GNU General Lesser Public + * License along with this program. If not, see + * <http://www.gnu.org/licenses/lgpl-3.0.html>. ##%* */ package fr.ifremer.isisfish.vcs; @@ -23,10 +22,12 @@ import java.io.FileFilter; import java.util.List; import java.util.Map; + import org.codelutin.util.VersionNumber; /** - * + * Version control system. + * * @author poussin * @version $Revision$ * @@ -34,33 +35,46 @@ * by : $Author$ */ public interface VCS extends FileFilter { + + /** CVS VCS Type */ public static final String TYPE_CVS = "cvs"; + + /** None CVS Type */ public static final String TYPE_NONE = "none"; + + /** SVN VCS Type */ public static final String TYPE_SVN = "svn"; + /** * can be None, CVS or SVN. only None or SVN work */ public static final String VCS_TYPE = "vcs.type"; + /** * can be http, ssh, pserver, ... */ public static final String VCS_PROTOCOLE = "vcs.protocol"; + /** * ssh key file */ public static final String VCS_SSH_KEY_FILE = "vcs.ssh.keyFile"; + /** * remote server adresse (ip or serveur name) ex: labs.libre-entreprise.org */ public static final String VCS_HOST_NAME = "vcs.hostName"; + /** * remote repository path ex: /svnroot/isis-fish-data */ public static final String VCS_PATH = "vcs.path"; + /** * user login to access vcs ex: bpoussin */ public static final String VCS_USER_NAME = "vcs.username"; + /** * user passwd or passphrase (protocole dependent) to access vcs ex: xxxxxxxx */ @@ -68,162 +82,193 @@ /** * Ajout un listener pouvant interdire les actions du vcs - * @param l + * + * @param l listener to add */ - public void addVetoableActionListener(VetoableActionListener l); + void addVetoableActionListener(VetoableActionListener l); /** * Supprime un listener pouvant interdire les actions du vcs - * @param l + * + * @param l listener to remove */ - public void remoteVetoableActionListener(VetoableActionListener l); + void remoteVetoableActionListener(VetoableActionListener l); /** * Get local repository directory + * + * @return local repository */ - public File getLocalRepository(); - + File getLocalRepository(); + /** - * Return true, if local repository is valid repository for actuel vcs - * @return + * Return true, if local repository is valid repository for actual vcs. + * + * @return validity */ - public boolean isValidLocalRepository(); - + boolean isValidLocalRepository(); + /** - * Return true, if local repository is writeable + * Return true, if local repository is writeable. * (use trunk and is not anonymous) - * @return + * + * @return writable + * @throws VCSException */ - public boolean isWriteable() throws VCSException; - + boolean isWriteable() throws VCSException; + /** - * Permit to force repository to read-only if value is false, otherwize + * Permit to force repository to read-only if value is false, otherwise * use normal rules. - * @param value + * + * @param value writable */ - public void setWriteable(boolean value); - + void setWriteable(boolean value); + /** - * Commit specified files, if files is null, all files are commited + * Commit specified files, if files is null, all files are commited. + * * @param files files to commit * @param msg message used to commit - * @throws fr.ifremer.isisfish.vcs.VCSException + * @throws org.codelutin.gesi.vcs.VCSException */ - public void commit(List<File> files, String msg) throws VCSException; - + void commit(List<File> files, String msg) throws VCSException; + /** - * Add and commit file in server repository + * Add and commit file in server repository. + * * @param files list of file to add * @param msg message for commit - * @throws fr.ifremer.isisfish.vcs.VCSException + * @throws org.codelutin.gesi.vcs.VCSException */ - public void add(List<File> files, String msg) throws VCSException; + void add(List<File> files, String msg) throws VCSException; /** - * get repository on server and put it in localdir + * get repository on server and put it in localdir. + * * @param tag tag to used, null = /trunk other is tags/[tag] * @param recurse if file is directory checkout sub file - * @throws fr.ifremer.isisfish.vcs.VCSException + * @throws org.codelutin.gesi.vcs.VCSException */ - public void checkout(VersionNumber tag, boolean recurse) throws VCSException; + void checkout(VersionNumber tag, boolean recurse) + throws VCSException; /** - * Delete and commit files in server repository + * Delete and commit files in server repository. + * * @param files file to delete * @param msg message for commit - * @throws fr.ifremer.isisfish.vcs.VCSException + * @throws VCSException */ - public void delete(List<File> files, String msg) throws VCSException; + void delete(List<File> files, String msg) throws VCSException; /** * Return all changelog between local file version and remote repository - * file version + * file version. + * * @param files * @return changelog for each file + * @throws VCSException */ - public Map<File, String> getChanglog(List<File> files) throws VCSException; + Map<File, String> getChanglog(List<File> files) throws VCSException; /** - * show diff between local file and repository file - * @param file - * @return - * @throws fr.ifremer.isisfish.vcs.VCSException + * show diff between local file and repository file. + * + * @param file file to get diff + * @return string diff + * @throws VCSException */ - public String getDiff(File file) throws VCSException; + String getDiff(File file) throws VCSException; /** - * Return list of all file on directory on remote server + * Return list of all file on directory on remote server. + * * @param directory - * @return + * @return files list + * @throws VCSException */ - public List<String> getFileList(File directory) throws VCSException; + List<String> getFileList(File directory) throws VCSException; /** - * get list of new or modified files on server + * get list of new or modified files on server. + * * @return list of modified or new files + * @throws VCSException */ - public List<File> getUpdatedFile() throws VCSException; + List<File> getUpdatedFile() throws VCSException; /** - * Ask if there are some new or modified files on server + * Ask if there are some new or modified files on server. + * * @return true if new file available + * @throws VCSException */ - public boolean haveUpdate() throws VCSException; + boolean haveUpdate() throws VCSException; /** * Get connection state. + * * @return true if server is connectable */ - public boolean isConnected(); + boolean isConnected(); /** - * Check if file is available on server + * Check if file is available on server. + * * @param file file to check * @return true if file available - * @throws fr.ifremer.isisfish.vcs.VCSException + * @throws VCSException */ - public boolean isOnRemote(File file) throws VCSException; + boolean isOnRemote(File file) throws VCSException; /** - * look on server if version is tag repository + * Look on server if version is tag repository. + * * @param version version number like 3.2 * @return true if tag found with this name + * @throws VCSException */ - public boolean isTag(VersionNumber version) throws VCSException; + boolean isTag(VersionNumber version) throws VCSException; /** - * Check if file is uptodate + * Check if file is uptodate. + * * @param file file to check * @return true if file is in last version - * @throws fr.ifremer.isisfish.vcs.VCSException + * @throws VCSException */ - public boolean isUpToDate(File file) throws VCSException; + boolean isUpToDate(File file) throws VCSException; /** - * Must be overwriten, this default implementation return true. * Check if file can be put in vcs repository, for example when you used * CVS, you must not put CVS file. * <p> * default refused .svn, CVS and ~ filename + * + * Must be override, this default implementation return true. * * @param file - * @return + * @return <tt>true</tt> if file is versionnable */ - public boolean isVersionnableAbleFile(File file); + boolean isVersionnableAbleFile(File file); /** - * Update file - * @param files files to update - * @return true if there are some merging conflict, false otherwize - * @throws fr.ifremer.isisfish.vcs.VCSException + * Update file. + * + * @param file files to update + * @param recurse + * @return true if there are some merging conflict, false otherwise + * @throws org.codelutin.gesi.vcs.VCSException */ - public List<File> update(File file, boolean recurse) throws VCSException; + List<File> update(File file, boolean recurse) throws VCSException; /** * Verifie la connexion et si le protocole a change, switch le repository * pour utiliser le nouveau protocole. Si on est en mode interface (mode * graphique) et que le switch se passe mal, demande a l'utilisateur * de nouvelle valeur pour le protocole (+ identifiant, ...) + * @throws VCSException */ void checkProtocol() throws VCSException; @@ -233,34 +278,53 @@ * en mode interactif (mode graphique), on lui propose de mettre a jour * les fichiers, avec la possibilite de voir les changements sur les * fichiers + * + * @throws VCSException */ void checkFileStatus() throws VCSException; -// /** -// * Verifie que l'utilisateur utilise la bonne version de script en fonction -// * de sa version de logiciel. Si ce n'est pas le cas et que l'on est en -// * interactif (mode graphique), on lui demande ce qu'il souhaite faire. -// */ -// void checkRelease(VersionNumber version) throws VCSException; - + /** + * TODO comment me + * @return host + */ String getHost(); + /** + * TODO comment me + * @return login + */ String getLogin(); + /** + * TODO comment me + * @return password + */ String getPassword(); + /** + * TODO comment me + * @return path + */ String getPath(); + /** + * TODO comment me + * @return protocole + */ String getProtocol(); + /** + * TODO comment me + * @return ssh key file + */ File getSshKeyFile(); /** * retourne le tag reellement utilise, par exemple si on a fait un * setTag(3.2.0) cette methode retourne "/tags/3.2.0", pour setTag(null) * on retourne "/trunk" - * @return - * @throws fr.ifremer.isisfish.vcs.VCSException + * @return tag + * @throws org.codelutin.gesi.vcs.VCSException */ String getTag() throws VCSException; @@ -269,36 +333,50 @@ * trunk. * @param version version to go, if null trunk is used, otherwize * tags/version is used - * @throws fr.ifremer.isisfish.vcs.VCSException + * @throws org.codelutin.gesi.vcs.VCSException */ - public void setTag(VersionNumber version) throws VCSException; - + void setTag(VersionNumber version) throws VCSException; + /** * checkProtocol is automaticaly done - * @param path + * + * @param host + * @throws VCSException */ void setHost(String host) throws VCSException; /** * checkProtocol is automaticaly done - * @param path + * + * @param login + * @throws VCSException */ void setLogin(String login) throws VCSException; + /** + * TODO comment me + * @param password password + */ void setPassword(String password); /** * checkProtocol is automaticaly done * @param path + * @throws VCSException */ void setPath(String path) throws VCSException; /** * checkProtocol is automaticaly done - * @param path + * @param protocol + * @throws VCSException */ void setProtocol(String protocol) throws VCSException; + /** + * TODO comment me + * @param sshKeyFile + */ void setSshKeyFile(File sshKeyFile); } Modified: isis-fish/trunk/src/main/java/fr/ifremer/isisfish/vcs/VCSSVN.java =================================================================== --- isis-fish/trunk/src/main/java/fr/ifremer/isisfish/vcs/VCSSVN.java 2008-11-27 11:28:02 UTC (rev 1621) +++ isis-fish/trunk/src/main/java/fr/ifremer/isisfish/vcs/VCSSVN.java 2008-11-27 11:45:40 UTC (rev 1622) @@ -1,56 +1,68 @@ -/* *##% - * Copyright (C) 2002-2008 Code Lutin, Benjamin Poussin - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, - * USA. - *##%*/ +/* *##% GeSi + * Copyright (C) 2008 CodeLutin + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Lesser Public License for more details. + * + * You should have received a copy of the GNU General Lesser Public + * License along with this program. If not, see + * <http://www.gnu.org/licenses/lgpl-3.0.html>. ##%*/ package fr.ifremer.isisfish.vcs; -import static org.codelutin.i18n.I18nf._; +import static org.codelutin.i18n.I18n._; +import java.io.ByteArrayOutputStream; import java.io.File; +import java.io.IOException; import java.util.ArrayList; import java.util.Arrays; import java.util.HashMap; import java.util.HashSet; -import java.util.LinkedList; import java.util.List; import java.util.Map; import java.util.Set; + import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.codelutin.util.VersionNumber; +import org.tmatesoft.svn.core.ISVNDirEntryHandler; import org.tmatesoft.svn.core.SVNCommitInfo; +import org.tmatesoft.svn.core.SVNDepth; +import org.tmatesoft.svn.core.SVNDirEntry; import org.tmatesoft.svn.core.SVNException; import org.tmatesoft.svn.core.SVNURL; import org.tmatesoft.svn.core.auth.ISVNAuthenticationManager; import org.tmatesoft.svn.core.internal.io.dav.DAVRepositoryFactory; import org.tmatesoft.svn.core.internal.io.fs.FSRepositoryFactory; import org.tmatesoft.svn.core.internal.io.svn.SVNRepositoryFactoryImpl; +import org.tmatesoft.svn.core.internal.wc.DefaultSVNOptions; import org.tmatesoft.svn.core.wc.ISVNOptions; import org.tmatesoft.svn.core.wc.ISVNStatusHandler; import org.tmatesoft.svn.core.wc.SVNClientManager; +import org.tmatesoft.svn.core.wc.SVNCommitClient; +import org.tmatesoft.svn.core.wc.SVNConflictChoice; +import org.tmatesoft.svn.core.wc.SVNDiffClient; import org.tmatesoft.svn.core.wc.SVNInfo; +import org.tmatesoft.svn.core.wc.SVNLogClient; import org.tmatesoft.svn.core.wc.SVNRevision; import org.tmatesoft.svn.core.wc.SVNStatus; +import org.tmatesoft.svn.core.wc.SVNStatusClient; import org.tmatesoft.svn.core.wc.SVNStatusType; +import org.tmatesoft.svn.core.wc.SVNUpdateClient; +import org.tmatesoft.svn.core.wc.SVNWCClient; import org.tmatesoft.svn.core.wc.SVNWCUtil; /** - * + * SVN VCS. + * * @author poussin * @version $Revision$ * @@ -60,19 +72,19 @@ public class VCSSVN extends AbstractVCS { /** to use log facility, just put in your code: log.info(\"...\"); */ - static private Log log = LogFactory.getLog(VCSSVN.class); - + protected static Log log = LogFactory.getLog(VCSSVN.class); + static enum ConnectionState { NOT_TESTED, OFF_LINE, ON_LINE } - + protected SVNClientManager svnManager = null; protected ConnectionState connectionState = ConnectionState.NOT_TESTED; - public VCSSVN(File localRepository, - String protocol, String host, String path, - File sshKeyFile, String login, String password) { - super(localRepository, protocol, host, path, sshKeyFile, login, password); + public VCSSVN(File localRepository, String protocol, String host, + String path, File sshKeyFile, String login, String password) { + super(localRepository, protocol, host, path, sshKeyFile, login, + password); if (protocol.startsWith("file")) { FSRepositoryFactory.setup(); } else if (protocol.startsWith("http")) { @@ -82,7 +94,7 @@ SVNRepositoryFactoryImpl.setup(); } } - + protected SVNClientManager getSVNManager() { if (svnManager == null) { String login = getLogin(); @@ -90,24 +102,30 @@ if (getProtocol().contains("ssh")) { ISVNOptions options = SVNWCUtil.createDefaultOptions(true); -// options.setPropertyValue("svnkit.ssh2.key", getSshKeyFile().getAbsolutePath()); -// options.setPropertyValue("svnkit.ssh2.username", login); -// if (passwd != null && !"".equals(passwd)) { -// options.setPropertyValue("svnkit.ssh2.passphrase", passwd); -// } - ISVNAuthenticationManager auth = - SVNWCUtil.createDefaultAuthenticationManager( - SVNWCUtil.getDefaultConfigurationDirectory(), - login, passwd, sshKeyFile, passwd, false); + // options.setPropertyValue("svnkit.ssh2.key", getSshKeyFile().getAbsolutePath()); + // options.setPropertyValue("svnkit.ssh2.username", login); + // if (passwd != null && !"".equals(passwd)) { + // options.setPropertyValue("svnkit.ssh2.passphrase", passwd); + // } + ISVNAuthenticationManager auth = SVNWCUtil + .createDefaultAuthenticationManager(SVNWCUtil + .getDefaultConfigurationDirectory(), login, + passwd, sshKeyFile, passwd, false); svnManager = SVNClientManager.newInstance(options, auth); } else { - ISVNOptions options = SVNWCUtil.createDefaultOptions(true); - svnManager = SVNClientManager.newInstance(options, login, passwd); + DefaultSVNOptions options = SVNWCUtil + .createDefaultOptions(true); + svnManager = SVNClientManager.newInstance(options, login, + passwd); } } return svnManager; } + /* + * @see org.codelutin.gesi.vcs.VCS#isValidLocalRepository() + */ + @Override public boolean isValidLocalRepository() { File local = getLocalRepository(); File svn = new File(local, ".svn"); @@ -115,17 +133,21 @@ return result; } + /* + * @see org.codelutin.gesi.vcs.VCS#isConnected() + */ + @Override public boolean isConnected() { if (connectionState == ConnectionState.NOT_TESTED) { try { SVNURL url = getRemoteURL(); getSVNManager().getWCClient().doGetProperty(url, "", - SVNRevision.HEAD, - SVNRevision.HEAD, false); + SVNRevision.HEAD, SVNRevision.HEAD); connectionState = ConnectionState.ON_LINE; - log.info(_("Connection to serveur available, switch on line: %s", + log.info(_( + "Connection to serveur available, switch on line: %s", getRemoteRepository())); - } catch(SVNException eee) { + } catch (SVNException eee) { log.info(_("Can't connect to serveur, switch to off line: %s", getRemoteRepository())); connectionState = ConnectionState.OFF_LINE; @@ -135,55 +157,65 @@ return result; } + /* + * @see org.codelutin.gesi.vcs.VCS#checkProtocol() + */ @Override public void checkProtocol() throws VCSException { try { File localRoot = getLocalRepository(); - SVNInfo info = getSVNManager().getWCClient().doInfo( - localRoot, SVNRevision.WORKING); + SVNInfo info = getSVNManager().getWCClient().doInfo(localRoot, + SVNRevision.WORKING); SVNURL url = info.getURL(); - SVNURL rootUrl = info.getRepositoryRootURL(); - String path = url.toDecodedString().substring(rootUrl.toDecodedString().length()); + + // FIXME path seems to appear twice + //SVNURL rootUrl = info.getRepositoryRootURL(); + //String path = url.toDecodedString().substring( + // rootUrl.toDecodedString().length()); + String path = url.getPath().substring( + getPath().length()); -// // si un des constituants de l'url a change on fait un switch relocate -// boolean mustSwitch = false; -// if (!url.getProtocol().equals(getProtocol())) { -// log.info(_("repository protocol change from %s to %s", -// url.getProtocol(), getProtocol())); -// mustSwitch = true; -// } -// if (!url.getUserInfo() != null !url.getUserInfo().equals(getLogin())) { -// log.info(_("repository user change from %s to %s", -// url.getUserInfo(), getLogin())); -// mustSwitch = true; -// } -// if (!url.getHost().equals(getHost())) { -// log.info(_("repository host change from %s to %s", -// url.getHost(), getHost())); -// mustSwitch = true; -// } -// -// if (mustSwitch) { + // // si un des constituants de l'url a change on fait un switch relocate + // boolean mustSwitch = false; + // if (!url.getProtocol().equals(getProtocol())) { + // log.info(_("repository protocol change from %s to %s", + // url.getProtocol(), getProtocol())); + // mustSwitch = true; + // } + // if (!url.getUserInfo() != null !url.getUserInfo().equals(getLogin())) { + // log.info(_("repository user change from %s to %s", + // url.getUserInfo(), getLogin())); + // mustSwitch = true; + // } + // if (!url.getHost().equals(getHost())) { + // log.info(_("repository host change from %s to %s", + // url.getHost(), getHost())); + // mustSwitch = true; + // } + // + // if (mustSwitch) { SVNURL newUrl = getRemoteURL(); newUrl = newUrl.appendPath(path, false); if (!url.equals(newUrl)) { if (fireAction(VCSActionEvent.SWITCH_PROTOCOL)) { -// String path = url.getPath(); -// int port = url.getPort(); -// SVNURL newUrl = SVNURL.create(getProtocol(), getLogin(), -// getHost(), port, path, true); - log.info(_("Switch repository %s from %s to %s", - localRoot, url, newUrl)); - getSVNManager().getUpdateClient().doRelocate(localRoot, url, newUrl, true); + // String path = url.getPath(); + // int port = url.getPort(); + // SVNURL newUrl = SVNURL.create(getProtocol(), getLogin(), + // getHost(), port, path, true); + log.info(_("Switch repository %s from %s to %s", localRoot, + url, newUrl)); + getSVNManager().getUpdateClient().doRelocate(localRoot, + url, newUrl, true); } } } catch (SVNException eee) { - throw new VCSException(_("Can't get address on serveur of local repository"), eee); + throw new VCSException( + _("Can't get address on serveur of local repository"), eee); } } - /** + /** * Verifie si tous les fichiers du repository local sont les dernieres * version par rapport au serveur. Si ce n'est pas le cas et que l'on est * en mode interactif (mode graphique), on lui propose de mettre a jour @@ -194,31 +226,40 @@ Map<File, SVNStatus> status = getRemoteStatus(null, true); // si des fichiers ont ete mis a jour sur le serveur on se synchronise if (status.size() > 0) { - if (fireAction(VCSActionEvent.UPDATE_REPOSITORY, - status.keySet().toArray(new File[status.size()]))) { + if (fireAction(VCSActionEvent.UPDATE_REPOSITORY, status.keySet() + .toArray(new File[status.size()]))) { update(null, true); } } } + /** + * Retourne l'url dans un objet SVNURL (svnkit). + * + * @see SVNURL + * @return l'url distante + * @throws SVNException + */ protected SVNURL getRemoteURL() throws SVNException { SVNURL remoteURL = SVNURL.parseURIEncoded(getRemoteRepository()); return remoteURL; } /** - * Retourne l'url du repository distant + * Retourne l'url du repository distant. + * * ex: ssh+svn://labs.le.org/svnroot/isis-fish/data/branches/3.2 - * @return + * + * @return remote repository url */ public String getRemoteRepository() { String proto = getProtocol(); String user = getLogin(); String host = getHost(); String path = getPath(); - + String result = null; - + if (proto.startsWith("file")) { result = proto + "://" + path; } else { @@ -233,53 +274,130 @@ return result; } + /* + * @see fr.ifremer.isisfish.vcs.AbstractVCS#isVersionnableAbleFile(java.io.File) + */ @Override public boolean isVersionnableAbleFile(File file) { + boolean result = super.isVersionnableAbleFile(file); - result = result && !getSVNManager().getOptions().isIgnored(file); + + //result = result && !getSVNManager().getOptions().isIgnored(file); + + if (result) { + // if result is true, file start with getLocalRepository().getAbsolutePath() + String fileName = file.getAbsolutePath(); + String fileEnd = fileName.substring(getLocalRepository() + .getAbsolutePath().length()); + + for (String pattern : getSVNManager().getOptions() + .getIgnorePatterns()) { + + String localPattern = pattern.replaceAll("\\.", "\\\\."); + localPattern = localPattern.replaceAll("\\*", ".*"); + + if (fileEnd.matches(localPattern)) { + + if (log.isDebugEnabled()) { + log.debug("file " + file + " match pattern : " + + localPattern + " (svn-ignore:" + pattern + + ")"); + } + + result &= false; + } + } + } + return result; } + /* + * @see org.codelutin.gesi.vcs.VCS#commit(java.util.List, java.lang.String) + */ + @Override public void commit(List<File> files, String msg) throws VCSException { + + // if can't commit if (!isWriteable()) { - throw new VCSException("You can't commit file, this repository is readonly"); + throw new VCSException( + "You can't commit file, this repository is readonly"); } - if (files == null) { - files = Arrays.asList(getLocalRepository()); + + // list to array + List<File> localFiles = files; + if (localFiles == null) { + localFiles = Arrays.asList(getLocalRepository()); } - if (fireAction(VCSActionEvent.COMMIT, files.toArray(new File[files.size()]))) { - commitWithoutCheck(files, msg); + + if (fireAction(VCSActionEvent.COMMIT, localFiles + .toArray(new File[localFiles.size()]))) { + commitWithoutCheck(localFiles, msg); } } - - protected void commitWithoutCheck(List<File> files, String msg) throws VCSException { + + /** + * + * @param files files to commit + * @param msg + * @throws VCSException + */ + protected void commitWithoutCheck(List<File> files, String msg) + throws VCSException { try { - SVNCommitInfo commitInfo = getSVNManager().getCommitClient() - .doCommit(files.toArray(new File[files.size()]), - false, // keep lock - msg, + // SVNCommitInfo commitInfo = getSVNManager().getCommitClient() + // .doCommit(files.toArray(new File[files.size()]), + // false, // keep lock + // msg, + // false, // force + // true); // recurse + + SVNCommitClient commitClient = getSVNManager().getCommitClient(); + + File[] filesToCommit = files.toArray(new File[files.size()]); + SVNCommitInfo commitInfo = commitClient.doCommit(filesToCommit, // paths + false, // keepLocks + msg, // commitMessage + null, // revisionProperties + null, // changelists + false, // keepChangelist false, // force - true); // recurse - log.debug("to revision " + commitInfo.getNewRevision()); + SVNDepth.INFINITY); // depth + + if (log.isDebugEnabled()) { + log.debug(_("to revision %d", commitInfo.getNewRevision())); + } } catch (SVNException eee) { throw new VCSException("Can't commit files", eee); } } - + public void add(List<File> files, String msg) throws VCSException { if (!isWriteable()) { - throw new VCSException("You can't add file, this repository is readonly"); + throw new VCSException( + "You can't add file, this repository is readonly"); } try { - if (fireAction(VCSActionEvent.ADD, files.toArray(new File[files.size()]))) { + if (fireAction(VCSActionEvent.ADD, files.toArray(new File[files + .size()]))) { for (File file : files) { // FIXME ajoute dans le ignore les fichiers regions/<region>/data/* - getSVNManager().getWCClient().doAdd(file, - true, // force add to allready added file (no error) - false, // don't create dir if not exist - true, // add parent dir if is not versionned - false, // no recurse - false); // don't add ignore file + + // getSVNManager().getWCClient().doAdd(file, + // true, // force add to allready added file (no error) + // false, // don't create dir if not exist + // true, // add parent dir if is not versionned + // false, // no recurse + // false); // don't add ignore file + + SVNWCClient wcClient = getSVNManager().getWCClient(); + wcClient.doAdd(file, // File path + true, // boolean force + false, // boolean mkdir + true, // boolean climbUnversionedParents + SVNDepth.FILES, // SVNDepth depth + false, // boolean includeIgnored + true); // boolean makeParents } commitWithoutCheck(files, msg); } @@ -288,7 +406,12 @@ } } - public void checkout(VersionNumber tag, boolean recurse) throws VCSException { + /* + * @see org.codelutin.gesi.vcs.VCS#checkout(org.codelutin.util.VersionNumber, boolean) + */ + @Override + public void checkout(VersionNumber tag, boolean recurse) + throws VCSException { try { if (fireAction(VCSActionEvent.CHECKOUT, getLocalRepository())) { String tagPath = "/trunk/"; @@ -301,8 +424,22 @@ File destDir = getLocalRepository(); destDir.mkdirs(); - getSVNManager().getUpdateClient().doCheckout(source, destDir, null, - SVNRevision.HEAD, recurse); + // getSVNManager().getUpdateClient().doCheckout(source, destDir, null, + // SVNRevision.HEAD, recurse); + + // since svnkit 1.2 + SVNUpdateClient updateClient = getSVNManager() + .getUpdateClient(); + long newRevision = updateClient.doCheckout(source, // SVNURL url + destDir, // File dstPath + null, // SVNRevision pegRevision + SVNRevision.HEAD, // SVNRevision revision + SVNDepth.INFINITY, // SVNDepth depth + true); // boolean allowUnversionedObstructions + + if (log.isDebugEnabled()) { + log.debug(_("to revision %d", newRevision)); + } } } catch (SVNException eee) { throw new VCSException(_("Can't checkout"), eee); @@ -311,15 +448,16 @@ public void delete(List<File> files, String msg) throws VCSException { if (!isWriteable()) { - throw new VCSException("You can't delete file, this repository is readonly"); + throw new VCSException( + "You can't delete file, this repository is readonly"); } try { - if (fireAction(VCSActionEvent.DELETE, files.toArray(new File[files.size()]))) { + if (fireAction(VCSActionEvent.DELETE, files.toArray(new File[files + .size()]))) { for (File file : files) { - getSVNManager().getWCClient().doDelete(file, - true, // force la deletion - true, // delete local file too - false); // is not just a test + getSVNManager().getWCClient().doDelete(file, true, // force la deletion + true, // delete local file too + false); // is not just a test } commitWithoutCheck(files, msg); } @@ -328,47 +466,43 @@ } } -// protected String statusToString(SVNStatus status) { -// SVNStatusType type = status.getRemoteContentsStatus(); -// -// String result = "'" + type.getCode() + "' '" + type.getID() + "' " + type.toString(); -// type = status.getContentsStatus(); -// result += "|'" + type.getCode() + "' '" + type.getID() + "' " + type.toString(); -// -// return result; -// } - /** - * Recherhce le status des fichiers locaux, ne retourne jamais les fichiers - * NOMAL ou NONE sauf si demande explicitement via wanted + * Recherche le statut des fichiers locaux, ne retourne jamais les fichiers + * NORMAL ou NONE sauf si demandé explicitement via wanted * * @param file le repertoire a partir duquel on souhaite le status * @param recurse si l'on souhaite le faire recursivement * @param wanted l'ensemble des status type que l'on recheche, si vide * recherche tous les statuts * @return une map avec comme cle le File local et en valeur le status - * @throws fr.ifremer.isisfish.vcs.VCSException + * @throws VCSException */ - protected Map<File, SVNStatus> getLocalStatus(File file, boolean recurse, SVNStatusType ... wanted) throws VCSException { + protected Map<File, SVNStatus> getLocalStatus(File file, boolean recurse, + SVNStatusType... wanted) throws VCSException { try { - if (file == null) { - file = getLocalRepository(); + + File localFile = file; + + if (localFile == null) { + localFile = getLocalRepository(); } final Map<File, SVNStatus> result = new HashMap<File, SVNStatus>(); - final Set<SVNStatusType> acceptedStatusType = - new HashSet<SVNStatusType>(Arrays.asList(wanted)); - + final Set<SVNStatusType> acceptedStatusType = new HashSet<SVNStatusType>( + Arrays.asList(wanted)); + ISVNStatusHandler handler = new ISVNStatusHandler() { public void handleStatus(SVNStatus status) throws SVNException { - if ((acceptedStatusType.size() == 0 && - status.getContentsStatus() != SVNStatusType.STATUS_NONE && - status.getContentsStatus() != SVNStatusType.STATUS_NORMAL) || - acceptedStatusType.contains(status.getContentsStatus())) { + if ((acceptedStatusType.size() == 0 + && status.getContentsStatus() != SVNStatusType.STATUS_NONE && status + .getContentsStatus() != SVNStatusType.STATUS_NORMAL) + || acceptedStatusType.contains(status + .getContentsStatus())) { File statusFile = status.getFile(); - if (statusFile.exists() && (!statusFile.isDirectory() || - status.getRemoteContentsStatus() == SVNStatusType.STATUS_ADDED || - status.getRemoteContentsStatus() == SVNStatusType.STATUS_DELETED)) { + if (statusFile.exists() + && (!statusFile.isDirectory() + || status.getRemoteContentsStatus() == SVNStatusType.STATUS_ADDED || status + .getRemoteContentsStatus() == SVNStatusType.STATUS_DELETED)) { // on ne met pas les repertoires pere dans le status // car en fait ca veut dire qu'un fichier/rep dans ce // repertoire a ete ajout/modifier/delete, et on l'aura @@ -378,38 +512,62 @@ } } }; - getSVNManager().getStatusClient().doStatus(file, - recurse, - false, // on remote - !acceptedStatusType.contains(SVNStatusType.STATUS_NORMAL), // report only change file, - acceptedStatusType.contains(SVNStatusType.STATUS_IGNORED), // includeIgnored, - handler); + // getSVNManager().getStatusClient().doStatus(file, + // recurse, + // false, // on remote + // !acceptedStatusType.contains(SVNStatusType.STATUS_NORMAL), // report only change file, + // acceptedStatusType.contains(SVNStatusType.STATUS_IGNORED), // includeIgnored, + // handler); + + SVNStatusClient statusClient = getSVNManager().getStatusClient(); + statusClient.doStatus(localFile, // File + SVNRevision.WORKING, // Revision + SVNDepth.INFINITY, // Depth + false, // remote + !acceptedStatusType.contains(SVNStatusType.STATUS_NORMAL), // reportAll + acceptedStatusType.contains(SVNStatusType.STATUS_IGNORED), // includeIgnored + false, // obsolete (not used) + handler, // handler + null); // changeLists + return result; } catch (SVNException eee) { throw new VCSException("Can't status file", eee); } } - protected Map<File, SVNStatus> getRemoteStatus(File file, boolean recurse, SVNStatusType ... wanted) throws VCSException { + /** + * @param file + * @param recurse + * @param wanted + * @return remote status + * @throws VCSException + */ + protected Map<File, SVNStatus> getRemoteStatus(File file, boolean recurse, + SVNStatusType... wanted) throws VCSException { try { - if (file == null) { - file = getLocalRepository(); + + File localFile = file; + if (localFile == null) { + localFile = getLocalRepository(); } - + final Map<File, SVNStatus> result = new HashMap<File, SVNStatus>(); - final Set<SVNStatusType> acceptedStatusType = - new HashSet<SVNStatusType>(Arrays.asList(wanted)); - + final Set<SVNStatusType> acceptedStatusType = new HashSet<SVNStatusType>( + Arrays.asList(wanted)); + ISVNStatusHandler handler = new ISVNStatusHandler() { public void handleStatus(SVNStatus status) throws SVNException { - if ((acceptedStatusType.size() == 0 && - status.getRemoteContentsStatus() != SVNStatusType.STATUS_NONE && - status.getRemoteContentsStatus() != SVNStatusType.STATUS_NORMAL) || - acceptedStatusType.contains(status.getRemoteContentsStatus())) { + if ((acceptedStatusType.size() == 0 + && status.getRemoteContentsStatus() != SVNStatusType.STATUS_NONE && status + .getRemoteContentsStatus() != SVNStatusType.STATUS_NORMAL) + || acceptedStatusType.contains(status + .getRemoteContentsStatus())) { File statusFile = status.getFile(); - if (statusFile.exists() && (!statusFile.isDirectory() || - status.getRemoteContentsStatus() == SVNStatusType.STATUS_ADDED || - status.getRemoteContentsStatus() == SVNStatusType.STATUS_DELETED)) { + if (statusFile.exists() + && (!statusFile.isDirectory() + || status.getRemoteContentsStatus() == SVNStatusType.STATUS_ADDED || status + .getRemoteContentsStatus() == SVNStatusType.STATUS_DELETED)) { // on ne met pas les repertoires pere dans le status // car en fait ca veut dire qu'un fichier/rep dans ce // repertoire a ete ajout/modifier/delete, et on l'aura @@ -419,78 +577,389 @@ } } }; - getSVNManager().getStatusClient().doStatus(file, - recurse, - true, // on remote - !acceptedStatusType.contains(SVNStatusType.STATUS_NORMAL), // report only change file, - acceptedStatusType.contains(SVNStatusType.STATUS_IGNORED), // includeIgnored, - handler); + + // getSVNManager().getStatusClient().doStatus(localFile, + // recurse, + // true, // on remote + // !acceptedStatusType.contains(SVNStatusType.STATUS_NORMAL), // report only change file, + // acceptedStatusType.contains(SVNStatusType.STATUS_IGNORED), // includeIgnored, + // handler); + + SVNStatusClient statusClient = getSVNManager().getStatusClient(); + statusClient.doStatus(localFile, // File path, + SVNRevision.HEAD, // SVNRevision revision, + SVNDepth.INFINITY, // SVNDepth depth, + true, // boolean remote, + !acceptedStatusType.contains(SVNStatusType.STATUS_NORMAL), // boolean reportAll, + acceptedStatusType.contains(SVNStatusType.STATUS_IGNORED), // boolean includeIgnored, + true, // boolean collectParentExternals, + handler, // ISVNStatusHandler handler, + null); // Collection changeLists + return result; } catch (SVNException eee) { throw new VCSException("Can't status file", eee); } } + + /** + * Return all changelog between local file version and remote repository + * file version. + * + * @param files + * @return changelog for each file + * @throws VCSException + */ + public Map<File, String> getChanglog(List<File> files) throws VCSException { + + throw new UnsupportedOperationException("Not supported yet."); + + /*final Map<File, String> changLog = new HashMap<File, String>(); + + try { + SVNInfo info = getSVNManager().getWCClient().doInfo(getLocalRepository(), + SVNRevision.WORKING); + final String path = info.getURL().getPath(); + + // Handler + ISVNLogEntryHandler handler = new ISVNLogEntryHandler() { - public Map<File, String> getChanglog(List<File> files) { - throw new UnsupportedOperationException("Not supported yet."); + @Override + public void handleLogEntry(SVNLogEntry logEntry) + throws SVNException { + + for (Map.Entry<String, SVNLogEntryPath> entry : (Set<Map.Entry<String, SVNLogEntryPath>>) logEntry + .getChangedPaths().entrySet()) { + + String path = entry.getKey(); + SVNLogEntryPath value = entry.getValue(); + + //log + if(log.isDebugEnabled()) { + log.debug("path changed : " + path + " = [" + value.getType() + "] " + logEntry.getMessage()); + } + + String path2 = SVNPathUtil.getRelativePath(getRemoteRepository(), value.getPath()); + + // tranform SVNLogEntryPath into file + String realPath = value.getPath().substring(getPath().length()); + File file = new File(getLocalRepository().getAbsoluteFile() + File.separator + realPath); + + changLog.put(file, logEntry.getMessage()); + + } + } + }; + + File[] filesToGetLog = files.toArray(new File[files.size()]); + + // do svn ls on remote + SVNLogClient logClient = getSVNManager().getLogClient(); + logClient.doLog(filesToGetLog, // File[] paths, + SVNRevision.WORKING, // SVNRevision startRevision, + SVNRevision.HEAD, // SVNRevision endRevision, + false, // boolean stopOnCopy, + true, // boolean discoverChangedPaths, + 20, // long limit, + handler); // ISVNLogEntryHandler handler + + } catch (SVNException e) { + throw new VCSException(_("Can't get changlog"), e); + } + + return changLog; */ + } + /** + * show diff between local file and repository file. + * + * @param file file to get diff + * @return string diff + * @throws VCSException + */ + @Override public String getDiff(File file) throws VCSException { - throw new UnsupportedOperationException("Not supported yet."); + + String diff = null; + + try { + ByteArrayOutputStream byte1 = new ByteArrayOutputStream(); + + SVNDiffClient diffClient = getSVNManager().getDiffClient(); + diffClient.doDiff(file, // File path1, + SVNRevision.WORKING, // SVNRevision rN, + file, // File path2, + SVNRevision.HEAD, // SVNRevision rM, + SVNDepth.IMMEDIATES, // SVNDepth depth, + false, // boolean useAncestry, + byte1, // OutputStream result, + null); // Collection changeLists + + diff = byte1.toString(); + byte1.close(); + + } catch (SVNException e) { + throw new VCSException(_("Can't get diff"), e); + } catch (IOException e) { + throw new VCSException(_("Can't get diff"), e); + } + + return diff; } + /* + * @see org.codelutin.gesi.vcs.VCS#getFileList(java.io.File) + */ + @Override public List<String> getFileList(File directory) throws VCSException { - throw new UnsupportedOperationException("Not supported yet."); + + File localFile = directory; + if (localFile == null) { + localFile = getLocalRepository(); + } + + // Handler + final List<String> files = new ArrayList<String>(); + ISVNDirEntryHandler handler = new ISVNDirEntryHandler() { + + @Override + public void handleDirEntry(SVNDirEntry dirEntry) + throws SVNException { + + String path = dirEntry.getRelativePath(); + // first path is "", exclude it + if (!path.isEmpty()) { + files.add(path); + } + } + }; + + try { + // do svn ls on remote + SVNLogClient logClient = getSVNManager().getLogClient(); + logClient.doList(localFile, // SVNURL url, + SVNRevision.HEAD, // SVNRevision pegRevision, + SVNRevision.HEAD, // SVNRevision revision, + false, // boolean fetchLocks, + SVNDepth.IMMEDIATES, // SVNDepth depth, + SVNDirEntry.DIRENT_ALL, // int entryFields, + handler); + } catch (SVNException e) { + throw new VCSException(_("Can't list files"), e); + } + + return files; } - public List<File> getUpdatedFile() { - throw new UnsupportedOperationException("Not supported yet."); + /** + * get list of new or modified files on server. + * + * @return list of modified or new files + * @throws VCSException + */ + public List<File> getUpdatedFile() throws VCSException { + + try { + + final List<File> result = new ArrayList<File>(); + + ISVNStatusHandler handler = new ISVNStatusHandler() { + public void handleStatus(SVNStatus status) throws SVNException { + + // log + if (log.isDebugEnabled()) { + log.debug(_("status for %s is %s", status.getFile() + .getAbsolutePath(), status + .getRemoteContentsStatus().toString())); + } + + if (status.getRemoteContentsStatus() == SVNStatusType.STATUS_ADDED + || status.getRemoteContentsStatus() == SVNStatusType.STATUS_MODIFIED) { + + // log + if (log.isDebugEnabled()) { + log.debug(_("add %s as updated file", status + .getFile().getAbsolutePath())); + } + result.add(status.getFile()); + + } + } + }; + + SVNStatusClient statusClient = getSVNManager().getStatusClient(); + statusClient.doStatus(getLocalRepository(), // File path, + SVNRevision.HEAD, // SVNRevision revision, + SVNDepth.INFINITY, // SVNDepth depth, + true, // boolean remote, + true, // boolean reportAll, + false, // boolean includeIgnored, + true, // boolean collectParentExternals, + handler, // ISVNStatusHandler handler, + null); // Collection changeLists + + return result; + } catch (SVNException eee) { + throw new VCSException("Can't status file", eee); + } } - public boolean haveUpdate() { - throw new UnsupportedOperationException("Not supported yet."); + /** + * Ask if there are some new or modified files on server. + * + * @return true if new file available + * @throws VCSException + */ + public boolean haveUpdate() throws VCSException { + + // c'est juste si la liste renvoyé par getUpdatedFile() n'est pas vide ? + List<File> updatedFiles = getUpdatedFile(); + + boolean result = false; + + if(updatedFiles != null && !updatedFiles.isEmpty()) { + result = true; + } + return result; } + /** + * Check if file is available on server. + * + * @param file file to check + * @return true if file available + * @throws VCSException + */ public boolean isOnRemote(File file) throws VCSException { - throw new UnsupportedOperationException("Not supported yet."); + + File localFile = file; + if (localFile == null) { + localFile = getLocalRepository(); + } + + boolean result = false; + + try { + SVNStatusClient statusClient = getSVNManager().getStatusClient(); + SVNStatus status = statusClient.doStatus(localFile, true /*remote*/); + + SVNStatusType localStatus = status.getContentsStatus(); + SVNStatusType remoteStatus = status.getRemoteContentsStatus(); + + if(log.isDebugEnabled()) { + log.debug(_("file %s status is (l:%s/r:%s)",localFile.getAbsolutePath(),localStatus, remoteStatus)); + } + + // don't return true if: + // - file is locally added + // - file is remotely deleted + if(!localStatus.equals(SVNStatusType.STATUS_ADDED) && !remoteStatus.equals(SVNStatusType.STATUS_DELETED)) { + result = true; + } + + } catch (SVNException e) { + // catch exception + // if exception, file doesn't exists on server + // result is still 'false' + if(log.isDebugEnabled()) { + log.debug(_("file %s is not on server",localFile.getAbsolutePath()),e); + } + } + + return result; } + /** + * Check if file is uptodate. + * + * @param file file to check + * @return true if file is in last version + * @throws VCSException + */ + @Override public boolean isUpToDate(File file) throws VCSException { + + File localFile = file; + if (localFile == null) { + localFile = getLocalRepository(); + } + + boolean result = false; + try { - SVNStatus status = getSVNManager().getStatusClient().doStatus(file, - true); // on remote - boolean result = true; // FIXME status.getContentsStatus(). - return result; + SVNStatusClient statusClient = getSVNManager().getStatusClient(); + SVNStatus status = statusClient.doStatus(localFile, true /*remote*/); + + SVNStatusType localStatus = status.getContentsStatus(); + SVNStatusType remoteStatus = status.getRemoteContentsStatus(); + + // TODO peut on dire que le fichier est à jour + // si le status local est normal et le distant est none + if (localStatus == SVNStatusType.STATUS_NORMAL && remoteStatus == SVNStatusType.STATUS_NONE) { + result = true; + } + } catch (SVNException eee) { - throw new VCSException("Can't add file", eee); + throw new VCSException(_("Can't get file status"), eee); } + + return result; } + /* + * @see org.codelutin.gesi.vcs.VCS#update(java.io.File, boolean) + */ + @Override public List<File> update(File file, boolean recurse) throws VCSException { List<File> result = new ArrayList<File>(); try { - if (file == null) { - file = getLocalRepository(); + + File localFile = file; + if (localFile == null) { + localFile = getLocalRepository(); } - if (!accept(file)) { - throw new VCSException("Can't update file that not in local repository"); + if (!accept(localFile)) { + throw new VCSException( + _("Can't update file that not in local repository")); } - if (fireAction(VCSActionEvent.UPDATE, file)) { + if (fireAction(VCSActionEvent.UPDATE, localFile)) { // si le repertoire pere, n'est pas encore dans le repo local // il faut aussi l'ajouter - if (!file.getParentFile().exists()) { - update(file.getParentFile(), false); + if (!localFile.getParentFile().exists()) { + update(localFile.getParentFile(), false); } - getSVNManager().getUpdateClient().doUpdate(file, SVNRevision.HEAD, recurse); + //getSVNManager().getUpdateClient().doUpdate(file, SVNRevision.HEAD, recurse); + + SVNUpdateClient updateClient = getSVNManager() + .getUpdateClient(); + long newRevision = updateClient.doUpdate(localFile, // File file + SVNRevision.HEAD, // SVNRevision revision + recurse ? SVNDepth.INFINITY : SVNDepth.FILES, // SVNDepth depth + false, // boolean allowUnversionedObstructions + false); // boolean depthIsSticky + + if (log.isInfoEnabled()) { + log.info(_("to revision %d", newRevision)); + } + // recherche de tous les fichiers locaux en conflit - Map<File, SVNStatus> status = getLocalStatus(file, recurse, SVNStatusType.STATUS_CONFLICTED); + Map<File, SVNStatus> status = getLocalStatus(localFile, + recurse, SVNStatusType.STATUS_CONFLICTED); if (status.size() > 0) { result.addAll(status.keySet()); // on supprime les conflits pour pouvoir commiter convenablement // les fichiers - getSVNManager().getWCClient().doResolve(file, recurse); + //getSVNManager().getWCClient().doResolve(localFile, recurse); + + // FIXME use conflit resolution choice ? + SVNWCClient wcClient = getSVNManager().getWCClient(); + wcClient.doResolve(localFile, // File file + recurse ? SVNDepth.INFINITY : SVNDepth.FILES, // depth + SVNConflictChoice.MERGED); // ConflictChoice } + } } catch (SVNException eee) { throw new VCSException("Can't update files", eee); @@ -498,6 +967,10 @@ return result; } + /* + * @see org.codelutin.gesi.vcs.VCS#isWriteable() + */ + @Override public boolean isWriteable() throws VCSException { // si on est clairement en anonyme @@ -505,7 +978,8 @@ if (writeable) { // check normal rules String login = getLogin(); - result = result && login != null && !"".equals(login) && !"anonymous".equals(login); + result = result && login != null && !"".equals(login) + && !"anonymous".equals(login); // meme s'il n'y a pas d'utilisateur, mais qu'on utilise le protocole file:// on est writeable result = result || getProtocol().startsWith("file"); // ou que le repertoire n'est pas utilisable pour ce type de vcs @@ -513,18 +987,23 @@ // ou que l'on est dans un tag, donc par convention not writeable result = result && !getTag().startsWith("/tags"); } - + // on indique que l'utilisateur n'a pas le droit d'ecrire return result; } + /* + * @see org.codelutin.gesi.vcs.VCS#isTag(org.codelutin.util.VersionNumber) + */ + @Override public boolean isTag(VersionNumber version) throws VCSException { boolean result = version == null; // le trunk exist toujours if (!result) { try { SVNURL url = getRemoteURL(); url = url.appendPath("tags/" + version, true); - SVNInfo info = getSVNManager().getWCClient().doInfo(url, null, SVNRevision.HEAD); + SVNInfo info = getSVNManager().getWCClient().doInfo(url, null, + SVNRevision.HEAD); // si le tag n'existe pas, on n'arrive pas ici car une exception // est leve, et donc result reste a faux result = info != null; @@ -535,33 +1014,42 @@ return result; } + /* + * @see org.codelutin.gesi.vcs.VCS#getTag() + */ + @Override public String getTag() throws VCSException { try { File localRoot = getLocalRepository(); - SVNInfo info = getSVNManager().getWCClient().doInfo( - localRoot, SVNRevision.WORKING); + SVNInfo info = getSVNManager().getWCClient().doInfo(localRoot, + SVNRevision.WORKING); String url = info.getURL().toDecodedString(); String result = "/trunk"; if (!url.endsWith("/trunk")) { // on est pas sur le trunk, on est soit sur un tag ou une // branche, dans les deux cas, il faut descendre de 2 / int i = url.lastIndexOf("/"); - i = url.lastIndexOf("/", i-1); + i = url.lastIndexOf("/", i - 1); result = url.substring(i); } return result; } catch (SVNException eee) { - throw new VCSException(_("Can't get address on serveur of local repository"), eee); + throw new VCSException( + _("Can't get address on serveur of local repository"), eee); } } + /* + * @see org.codelutin.gesi.vcs.VCS#setTag(org.codelutin.util.VersionNumber) + */ + @Override public void setTag(VersionNumber version) throws VCSException { try { String tag = "/trunk"; if (version != null) { tag = "/tags/" + version; } - + String currantTag = getTag(); if (!tag.equals(currantTag)) { // on ne fait le switch que si le tag change rellement, sinon @@ -573,15 +1061,33 @@ SVNURL newUrl = getRemoteURL(); newUrl = newUrl.appendPath(tag, true); - log.info(_("Switch repository tag from %s to %s", - currantTag, tag)); - getSVNManager().getUpdateClient().doSwitch( - localRoot, newUrl, SVNRevision.HEAD, true); + if (log.isInfoEnabled()) { + log.info(_("Switch repository tag from %s to %s", + currantTag, tag)); + } + //getSVNManager().getUpdateClient().doSwitch( + // localRoot, newUrl, SVNRevision.HEAD, true); + + // svnkit 1.3 code + SVNUpdateClient updateClient = getSVNManager() + .getUpdateClient(); + long newRevision = updateClient.doSwitch(localRoot, // File path + newUrl, // SVNURL url + SVNRevision.HEAD, // SVNRevision pegRevision + SVNRevision.HEAD, // SVNRevision revision + SVNDepth.INFINITY, // SVNDepth depth + false, // boolean allowUnversionedObstructions + true);// boolean depthIsSticky + + if (log.isInfoEnabled()) { + log.info(_("to revision %d", newRevision)); + } } } } catch (SVNException eee) { - throw new VCSException(_("Can't get address on serveur of local repository"), eee); + throw new VCSException( + _("Can't get address on serveur of local repository"), eee); } } - -} + +} \ No newline at end of file Modified: isis-fish/trunk/src/test/java/fr/ifremer/isisfish/vcs/VCSSVNTest.java =================================================================== --- isis-fish/trunk/src/test/java/fr/ifremer/isisfish/vcs/VCSSVNTest.java 2008-11-27 11:28:02 UTC (rev 1621) +++ isis-fish/trunk/src/test/java/fr/ifremer/isisfish/vcs/VCSSVNTest.java 2008-11-27 11:45:40 UTC (rev 1622) @@ -1,208 +1,287 @@ -/* - * Copyright (C) 2002-2008 Code Lutin, Benjamin Poussin - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, - * USA. - */ +/* *##% GeSi + * Copyright (C) 2008 CodeLutin + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Lesser Public License for more details. + * + * You should have received a copy of the GNU General Lesser Public + * License along with this program. If not, see + * <http://www.gnu.org/licenses/lgpl-3.0.html>. ##%*/ package fr.ifremer.isisfish.vcs; import java.io.File; +import java.io.IOException; import java.util.ArrayList; import java.util.Arrays; import java.util.HashMap; import java.util.List; import java.util.Map; -import junit.framework.TestCase; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; import org.codelutin.util.FileUtil; import org.codelutin.util.VersionNumber; - +import org.junit.After; +import org.junit.Assert; +import org.junit.Before; +import org.junit.BeforeClass; +import org.junit.Ignore; +import org.junit.Test; +import org.tmatesoft.svn.core.SVNDepth; +import org.tmatesoft.svn.core.SVNException; import org.tmatesoft.svn.core.SVNURL; import org.tmatesoft.svn.core.io.SVNRepositoryFactory; import org.tmatesoft.svn.core.wc.SVNClientManager; +import org.tmatesoft.svn.core.wc.SVNCopySource; import org.tmatesoft.svn.core.wc.SVNRevision; +import org.tmatesoft.svn.core.wc.SVNStatus; +import org.tmatesoft.svn.core.wc.SVNWCClient; /** - * + * Class de test VCS. + * + * Created: 12 janv. 2006 16:20:33 + * * @author poussin + * + * @version $Revision: 1526 $ + * + * Last update: $Date: 2008-10-07 18:46:13 +0200 (mar 07 oct 2008) $ by : $Author: tchemit $ */ -public class VCSSVNTest extends TestCase { +public class VCSSVNTest { - static VCSSVN instance = null; - + /** Class logger */ + private static Log log = LogFactory.getLog(VCSSVNTest.class); + + public static final String TMPDIR = System.getProperty("java.io.tmpdir"); + + public static final String FILECONTENTTAG = "Version 3.1.0"; + public static final String FILECONTENTTRUNK = "Version 3.2.0"; + + protected static File template; + protected static File remoteRepo; + protected static File localRepo; + protected static File localRepoTrunk; + + protected VCSSVN vcs = null; + + /** + * Constructor. + */ public VCSSVNTest() { + } + + /** + * Static test init. + */ + @BeforeClass + public static void init() { + template = new File(TMPDIR + "/testsvn-template"); + remoteRepo = new File(TMPDIR + "/testsvn-repo"); + localRepo = new File(TMPDIR + "/testsvn-local"); + localRepoTrunk = new File(TMPDIR + "/testsvn-localTrunk"); + } - static final String fileContentTag = "Version 3.1.0"; - static final String fileContentTrunk = "Version 3.2.0"; + /** + * Clean repo directories. + */ + @Ignore + protected void clean() { + // un peu de nettoyage + if (template.exists()) { + FileUtil.deleteRecursively(template); + } + if (remoteRepo.exists()) { + FileUtil.deleteRecursively(remoteRepo); + } + if (localRepo.exists()) { + FileUtil.deleteRecursively(localRepo); + } + if (localRepoTrunk.exists()) { + FileUtil.deleteRecursively(localRepoTrunk); + } + } - static File template = new File("/tmp/testsvn-template"); - static File remoteRepo = new File("/tmp/testsvn-repo"); - static File localRepo = new File("/tmp/testsvn-local"); - static File localRepoTrunk = new File("/tmp/testsvn-localTrunk"); + /** + * Init call before each test. + * @throws IOException + * @throws SVNException + */ + @Before + public void setUp() throws IOException, SVNException { + + // un peu de nettoyage + clean(); + + // creation de l'instance de notre VCS pour les tests + // on le fait au debut pour que la l'init de la lib svn soit fait + // par la classe elle meme et ainsi tester que ca marche + vcs = new VCSSVN( + localRepo, + "file", + "", + remoteRepo.getAbsolutePath() + "/isis-fish-data", + null, + "", ""); + + // Creation d'un repo local avec un trunk et un tag + // durant le test, on modifie version.txt pour utiliser + // fileContentTrunk et modifier le contenu. On peut alors tester + // le changement de tag en fonction du contenu du fichier + + // creation d'un template de directory + new File(template, "regions" + File.separator + "DemoRegion" + File.separator + "data").mkdirs(); + new File(template, "simulations" + File.separator + "simu1" + File.separator + "data").mkdirs(); + new File(template, "scripts").mkdirs(); - static { - try { - // un peu de nettoyage - if (template.exists()) { - FileUtil.deleteRecursively(template); - } - if (remoteRepo.exists()) { - FileUtil.deleteRecursively(remoteRepo); - } - if (localRepo.exists()) { - FileUtil.deleteRecursively(localRepo); - } - if (localRepoTrunk.exists()) { - FileUtil.deleteRecursively(localRepoTrunk); - } - - // creation de l'instance de notre VCS pour les tests - // on le fait au debut pour que la l'init de la lib svn soit fait - // par la classe elle meme et ainsi tester que ca marche - instance = new VCSSVN( - localRepo, - "file", - "", - remoteRepo.getAbsolutePath() + "/" + "isis-fish-data", - null, - "", ""); + FileUtil.writeString(new File(template, "scripts" + File.separator + "version.txt"), FILECONTENTTAG); + // creation du repo pour les tests + SVNRepositoryFactory.createLocalRepository(remoteRepo, false, true); + + // ajout de source dans le repo + SVNURL svnURL = SVNURL.parseURIDecoded("file://" + remoteRepo.getAbsolutePath()); + SVNURL svnRoot = svnURL.appendPath("isis-fish-data", false); + SVNURL svnTrunk = svnRoot.appendPath("trunk", false); + SVNURL svnTags = svnRoot.appendPath("tags", false); + + SVNClientManager svnManager = SVNClientManager.newInstance(); + // creation de l'arborescence + svnManager.getCommitClient().doMkDir(new SVNURL[]{svnRoot, svnTrunk, svnTags}, "add dir"); + //svnManager.getCommitClient().doImport(template, svnTrunk, "initial import", true, true); + svnManager.getCommitClient().doImport(template, svnTrunk, "initial import", null, true, true, SVNDepth.INFINITY); - /////////////////////////////////////////////////////////////////// - // - // Creation d'un repo local avec un trunk et un tag - // durant le test, on modifie version.txt pour utiliser - // fileContentTrunk et modifier le contenu. On peut alors tester - // le changement de tag en fonction du contenu du fichier - /////////////////////////////////////////////////////////////////// - - // creation d'un template de directory - new File(template, "regions" + File.separator + "DemoRegion" + File.separator + "data").mkdirs(); - new File(template, "simulations" + File.separator + "simu1" + File.separator + "data").mkdirs(); - new File(template, "scripts").mkdirs(); - FileUtil.writeString(new File(template, "scripts" + File.separator + "version.txt"), fileContentTag); - - // creation du repo pour les tests - SVNRepositoryFactory.createLocalRepository(remoteRepo, false, true); - - // ajout de source dans le repo - SVNURL svnURL = SVNURL.parseURIDecoded("file://" + remoteRepo.getAbsolutePath()); - SVNURL svnRoot = svnURL.appendPath("isis-fish-data", false); - SVNURL svnTrunk = svnRoot.appendPath("trunk", false); - SVNURL svnTags = svnRoot.appendPath("tags", false); - - SVNClientManager svnManager = SVNClientManager.newInstance(); - // creation de l'arborescence - svnManager.getCommitClient().doMkDir(new SVNURL[]{svnRoot, svnTrunk, svnTags}, "add dir"); - svnManager.getCommitClient().doImport(template, svnTrunk, "initial import", true, true); + // 1.1.x svnManager.getCopyClient().doCopy(svnTrunk, SVNRevision.HEAD, svnTags.appendPath("3.1.0", false), false, true, "Create tag"); + SVNCopySource source = new SVNCopySource(SVNRevision.HEAD, SVNRevision.HEAD, svnTrunk); + + svnManager.getCopyClient().doCopy( + new SVNCopySource[]{source}, + svnTags.appendPath("3.1.0", false), + false, /*isMove*/ + true, /*makeParents*/ + true, /*failWhenDstExists*/ + "Create tag", + null); - svnManager.getCopyClient().doCopy(svnTrunk, SVNRevision.HEAD, svnTags.appendPath("3.1.0", false), false, true, "Create tag"); - - - -// instance = new VCSSVN( -// new File("/tmp/testsvn"), -//// "svn+ssh", -// "file", -// "localhost", -// "/tmp/svnkit/repos/isis-fish-data", -// new File("/home/poussin/.ssh/id_dsa"), -// "poussin", ""); - -// instance = new VCSSVN( -// new File("/tmp/testsvn"), -// "svn", -// "labs.libre-entreprise.org", -// "/svnroot/isis-fish-data", -// null, -// "anonymous", "anonymous"); - -// instance = new VCSSVN( -// new File("/tmp/testsvn"), -// "svn+ssh", -// "labs.libre-entreprise.org", -// "/svnroot/isis-fish-data", -// null, -// "anonymous", "anonymous"); - } catch (Exception eee) { - throw new RuntimeException(eee); - } } - - @Override - protected void tearDown() throws Exception { + + /** + * After each test. + */ + @After + public void tearDown() { + // un peu de nettoyage + //clean(); } - + /** * Test of getSVNManager method, of class VCSSVN. */ - //@Test + @Test public void testgetSVNManager() { - System.out.println("getSVNManager"); - SVNClientManager result = instance.getSVNManager(); - assertNotNull(result); + + // log + if(log.isInfoEnabled()) { + log.info("testgetSVNManager()"); + } + + SVNClientManager result = vcs.getSVNManager(); + Assert.assertNotNull(result); } - + /** * Test of getRemoteURL method, of class VCSSVN. + * @throws SVNException */ - //@Test - public void testgetRemoteURL() throws Exception { - System.out.println("getRemoteURL"); + @Test + public void testgetRemoteURL() throws SVNException { + + // log + if(log.isInfoEnabled()) { + log.info("testgetRemoteURL()"); + } + SVNURL expResult = SVNURL.create("file", null, "", -1, - remoteRepo.getAbsolutePath() + "/" + "isis-fish-data", true); - SVNURL result = instance.getRemoteURL(); - assertEquals(expResult, result); + remoteRepo.getAbsolutePath() + "/" + "isis-fish-data", true); + SVNURL result = vcs.getRemoteURL(); + Assert.assertEquals(expResult, result); + } /** * Test of isVersionnableAbleFile method, of class VCSSVN. */ - //@Test - public void testisVersionnableAbleFile() { - System.out.println("isVersionnableAbleFile"); - { - // un fichier special, on refuse - File file = new File(".svn"); - boolean expResult = false; - boolean result = instance.isVersionnableAbleFile(file); - assertEquals(expResult, result); + @Test + public void testIsVersionnableAbleFile() { + + // log + if(log.isInfoEnabled()) { + log.info("testIsVersionnableAbleFile()"); } - { - // Pas dans le repository local, on refuse - File file = new File("Toto.java"); - boolean expResult = false; - boolean result = instance.isVersionnableAbleFile(file); - assertEquals(expResult, result); - } - { - // enfin un bout fichier :) - File file = new File(instance.getLocalRepository(), "Toto.java"); - boolean expResult = true; - boolean result = instance.isVersionnableAbleFile(file); - assertEquals(expResult, result); - } + + // un fichier special, on refuse + File file = new File(".svn"); + boolean result = vcs.isVersionnableAbleFile(file); + Assert.assertFalse(result); + + // Pas dans le repository local, on refuse + file = new File("Toto.java"); + result = vcs.isVersionnableAbleFile(file); + Assert.assertEquals(false, result); + + // enfin un bout fichier :) + file = new File(vcs.getLocalRepository(), "Toto.java"); + result = vcs.isVersionnableAbleFile(file); + Assert.assertEquals(true, result); + + // match pas (svn ignore) + file = new File(vcs.getLocalRepository(), "libaudio.la"); + result = vcs.isVersionnableAbleFile(file); + Assert.assertFalse(result); + + // match pas (svn ignore) + file = new File(vcs.getLocalRepository(), "libaudio.lo"); + result = vcs.isVersionnableAbleFile(file); + Assert.assertFalse(result); + + // match (svn ignore) + file = new File(vcs.getLocalRepository(), "libaudio.lads"); + result = vcs.isVersionnableAbleFile(file); + Assert.assertTrue(result); + + // match pas (svn ignore) + file = new File(vcs.getLocalRepository(), "libaudio.lads~"); + result = vcs.isVersionnableAbleFile(file); + Assert.assertFalse(result); + + // match pas (svn ignore) + file = new File(vcs.getLocalRepository(), "commit.rev1234.rej"); + result = vcs.isVersionnableAbleFile(file); + Assert.assertFalse(result); } /** * Test of checkout method, of class VCSSVN. + * @throws IOException + * @throws VCSException */ - //@Test - public void testAll() throws Exception { - System.out.println("checkout"); + @Test + public void testAll() throws IOException, VCSException { + + // log + if(log.isInfoEnabled()) { + log.info("testIsVersionnableAbleFile()"); + } + // trunk contient une copie complete de trunk, elle permet de test // status lors que l'on fait des commits sur le trunk sur instance VCSSVN trunk = new VCSSVN( @@ -212,215 +291,665 @@ remoteRepo.getAbsolutePath() + "/" + "isis-fish-data", null, "", ""); + trunk.checkout(null, true); - + // on ne checkout rien juste le .svn dans le repertoire racine - instance.checkout(null, false); - assertTrue(instance.getLocalRepository().exists()); - assertTrue(instance.getTag().startsWith("/trunk")); + vcs.checkout(null, false); + Assert.assertTrue(vcs.getLocalRepository().exists()); + Assert.assertTrue(vcs.getTag().startsWith("/trunk")); // update scripts dir - instance.update(new File(instance.getLocalRepository(), "scripts"), true); - File version = new File(instance.getLocalRepository(), "scripts" + File.separator + "version.txt"); - assertTrue(version.exists()); - assertEquals(fileContentTag, FileUtil.readAsString(version)); + vcs.update(new File(vcs.getLocalRepository(), "scripts"), true); + File version = new File(vcs.getLocalRepository(), "scripts" + File.separator + "version.txt"); + Assert.assertTrue(version.exists()); + Assert.assertEquals(FILECONTENTTAG, FileUtil.readAsString(version)); // modification du fichier version.txt - FileUtil.writeString(version, fileContentTrunk); - instance.commit(null, "modif du fichier version"); - assertEquals(fileContentTrunk, FileUtil.readAsString(version)); + FileUtil.writeString(version, FILECONTENTTRUNK); + vcs.commit(null, "modif du fichier version"); + Assert.assertEquals(FILECONTENTTRUNK, FileUtil.readAsString(version)); // recuperation de DemoRegion - File demo = new File(instance.getLocalRepository(), "regions" + File.separator + "DemoRegion"); - instance.update(demo, true); - assertTrue(demo.exists()); + File demo = new File(vcs.getLocalRepository(), "regions" + File.separator + "DemoRegion"); + vcs.update(demo, true); + Assert.assertTrue(demo.exists()); // suppression de DemoRegion - instance.delete(Arrays.asList(demo), "suppression d'une region"); - assertFalse(demo.exists()); + vcs.delete(Arrays.asList(demo), "suppression d'une region"); + Assert.assertFalse(demo.exists()); // ajout d'un fichier sur le trunk avant passage sur le tag - File fileToAdd = new File(instance.getLocalRepository(), "newfile.txt"); + File fileToAdd = new File(vcs.getLocalRepository(), "newfile.txt"); String lecontent = "Le nouveau fichier"; FileUtil.writeString(fileToAdd, lecontent); - instance.add(Arrays.asList(fileToAdd), "ajout d'un fichier"); + vcs.add(Arrays.asList(fileToAdd), "ajout d'un fichier"); // test switchTag - instance.setTag(new VersionNumber(3, 1, 0)); - assertTrue(instance.getTag().startsWith("/tags/3.1.0")); - assertEquals(fileContentTag, FileUtil.readAsString(version)); - assertTrue(demo.exists()); + vcs.setTag(new VersionNumber(3, 1, 0)); + Assert.assertTrue(vcs.getTag().startsWith("/tags/3.1.0")); + Assert.assertEquals(FILECONTENTTAG, FileUtil.readAsString(version)); + Assert.assertTrue(demo.exists()); // recherche du status des fichiers File fileVersion = new File(trunk.getLocalRepository(), "scripts" + File.separator + "version.txt"); File fileDeleted = new File(trunk.getLocalRepository(), "regions" + File.separator + "DemoRegion"); - Map map = trunk.getRemoteStatus(trunk.getLocalRepository(), true); - assertEquals(2, map.size()); // version.txt modifie, DemoRegion supprimee - assertTrue(map.containsKey(fileVersion)); - assertTrue(map.containsKey(fileDeleted)); + Map<File, SVNStatus> map = trunk.getRemoteStatus(trunk.getLocalRepository(), true); + Assert.assertEquals(2, map.size()); // version.txt modifie, DemoRegion supprimee + Assert.assertTrue(map.containsKey(fileVersion)); + Assert.assertTrue(map.containsKey(fileDeleted)); // modif dans repo trunk de version pour qu'il y ait un conflit FileUtil.writeString(fileVersion, "Le nouveau content de version"); // update global du repo trunk List<File> conflictFile = trunk.update(null, true); - System.out.println("conflictFile: " + conflictFile); - assertEquals(1, conflictFile.size()); - assertTrue(conflictFile.contains(fileVersion)); + if(log.isInfoEnabled()) { + log.info("conflictFile: " + conflictFile.toString()); + } + Assert.assertEquals(1, conflictFile.size()); + Assert.assertTrue(conflictFile.contains(fileVersion)); File fileAdded = new File(trunk.getLocalRepository(), "newfile.txt"); - assertEquals(lecontent, FileUtil.readAsString(fileAdded)); - assertFalse(fileDeleted.exists()); + Assert.assertEquals(lecontent, FileUtil.readAsString(fileAdded)); + Assert.assertFalse(fileDeleted.exists()); // recherche du status des fichiers en remote, il ne doit plus y avoir de diff - Map map2 = trunk.getRemoteStatus(trunk.getLocalRepository(), true); - assertEquals(0, map2.size()); + Map<File, SVNStatus> map2 = trunk.getRemoteStatus(trunk.getLocalRepository(), true); + Assert.assertEquals(0, map2.size()); // il doit toujours y avoir version.txt qui est modifier localement - Map map3 = trunk.getLocalStatus(trunk.getLocalRepository(), true); - assertEquals(1, map3.size()); - assertTrue(map3.containsKey(fileVersion)); + Map<File, SVNStatus> map3 = trunk.getLocalStatus(trunk.getLocalRepository(), true); + Assert.assertEquals(1, map3.size()); + Assert.assertTrue(map3.containsKey(fileVersion)); // on commit le fichier version.txt pour verifier qu'en local et remote // il n'y a plus de modif trunk.commit(Arrays.asList(fileVersion), "Commit fichier version, avec les conflits"); - Map map4 = trunk.getRemoteStatus(trunk.getLocalRepository(), true); - assertEquals(0, map4.size()); - Map map5 = trunk.getLocalStatus(trunk.getLocalRepository(), true); - assertEquals(0, map5.size()); - + Map<File, SVNStatus> map4 = trunk.getRemoteStatus(trunk.getLocalRepository(), true); + Assert.assertEquals(0, map4.size()); + Map<File, SVNStatus> map5 = trunk.getLocalStatus(trunk.getLocalRepository(), true); + Assert.assertEquals(0, map5.size()); } - - + /** * Test of add method, of class VCSSVN. + * @throws VCSException */ - //@Test - public void testadd() throws Exception { - System.out.println("add"); + @Test + public void testAdd() throws VCSException { + + // log + if(log.isInfoEnabled()) { + log.info("testAdd()"); + } + List<File> files = new ArrayList<File>(); String msg = ""; - instance.setTag(new VersionNumber(3, 1, 0)); + + // checkout a TAG + vcs.checkout(new VersionNumber(3, 1, 0),false); + try { - instance.add(files, msg); - assertFalse("Une exception aurait du etre leve, car instance est" + - " sur un tag, donc en readonly", true); - } catch(VCSException eee) { - assertTrue("On a bien pas la droit d'ajouter des fichiers", true); + vcs.add(files, msg); + + Assert.fail("Une exception aurait du etre leve, car instance est" + + " sur un tag, donc en readonly"); + } catch (VCSException e) { + // l'exception est normal et fait partie du test + if(log.isDebugEnabled()) { + log.debug("VCSException has normally been thrown : " + e.getMessage()); + } } } - + /** - * Test of getChanglog method, of class VCSSVN. + * Verifie la connexion et si le protocole a change, switch le repository + * pour utiliser le nouveau protocole. Si on est en mode interface (mode + * graphique) et que le switch se passe mal, demande a l'utilisateur + * de nouvelle valeur pour le protocole (+ identifiant, ...) + * @throws VCSException */ - //@Test - public void testgetChanglog() { - System.out.println("getChanglog"); + @Test + public void testCheckProtocol() throws VCSException { + + vcs.checkout(null, false); + + vcs.checkProtocol(); + } + + /** + * Return all changelog between local file version and remote repository + * file version. + * @throws VCSException + * @throws IOException + * @throws SVNException + * + */ + @Ignore + public void testGetChanglog() throws VCSException, IOException, SVNException { + + // log + if(log.isInfoEnabled()) { + log.info("testGetChanglog()"); + } + + File firstFile = new File(vcs.getLocalRepository() + File.separator + "scripts" + File.separator + "version.txt"); + File secondFile = new File(vcs.getLocalRepository() + File.separator + "simulations" + File.separator + "simu1" + File.separator + "simulation.properties"); List<File> files = new ArrayList<File>(); + files.add(firstFile); + files.add(secondFile); + Map<File, String> expResult = new HashMap<File, String>(); - Map<File, String> result = instance.getChanglog(files); - assertEquals(expResult, result); + expResult.put(new File("ooo"), "eee"); + + // first, checkout trunk + vcs.checkout(null, true); + + // now, make a modification, on LOCAL repo + FileUtil.writeString(firstFile, "version 3.2.1"); + FileUtil.writeString(secondFile, "name = test1"); + SVNClientManager svnManager = SVNClientManager.newInstance(); + svnManager.getWCClient().doAdd( + secondFile, // File path + true, // boolean force + false, // boolean mkdir + true, // boolean climbUnversionedParents + SVNDepth.FILES, // SVNDepth depth + false, // boolean includeIgnored + true); // boolean makeParents + svnManager.getCommitClient().doCommit(new File[]{firstFile, secondFile}, false, + "mise a jour de la version", null, null, false, true, SVNDepth.INFINITY); + + Map<File, String> result = vcs.getChanglog(files); + Assert.assertEquals(expResult, result); } /** * Test of getDiff method, of class VCSSVN. + * @throws VCSException + * @throws IOException */ - //@Test - public void testgetDiff() throws Exception { - System.out.println("getDiff"); - File file = null; - String expResult = ""; - String result = instance.getDiff(file); - assertEquals(expResult, result); + @Test + public void testGetDiff() throws VCSException, IOException { + + // log + if(log.isInfoEnabled()) { + log.info("testGetDiff()"); + } + + File firstFile = new File(vcs.getLocalRepository() + File.separator + "scripts" + File.separator + "version.txt"); + + vcs.checkout(null, true); + + // now, make a modification, on LOCAL repo + FileUtil.writeString(firstFile, "Version 3.2.1"); + + String result = vcs.getDiff(firstFile); + + // quelques tests sur la sortie, pas + // d'égalité parfaite + Assert.assertTrue(result.indexOf("version.txt") > 0); + Assert.assertTrue(result.indexOf("-Version 3.1.0") > 0); + Assert.assertTrue(result.indexOf("+Version 3.2.1") > 0); + } /** * Test of getFileList method, of class VCSSVN. + * @throws VCSException */ - //@Test - public void testgetFileList() throws Exception { - System.out.println("getFileList"); + @Test + public void testGetFileList() throws VCSException { + + // log + if(log.isInfoEnabled()) { + log.info("testGetFileList()"); + } + + vcs.checkout(null, true); + File directory = null; - List<String> expResult = null; - List<String> result = instance.getFileList(directory); - assertEquals(expResult, result); + List<String> expResult = new ArrayList<String>(3); + expResult.add("regions"); + expResult.add("scripts"); + expResult.add("simulations"); + List<String> result = vcs.getFileList(directory); + Assert.assertEquals(expResult, result); } + + /** + * Test of getFileList method, of class VCSSVN. + * @throws VCSException + * @throws SVNException + */ + @Test + public void testGetFileList2() throws VCSException, SVNException { + + // log + if(log.isInfoEnabled()) { + log.info("testGetFileList2()"); + } + vcs.checkout(null, true); + + // add new directory + File newDir = new File(vcs.getLocalRepository() + "/testadddir"); + newDir.mkdir(); + + SVNWCClient wcClient = vcs.getSVNManager().getWCClient(); + wcClient.doAdd( + newDir, // File path + true, // boolean force + false, // boolean mkdir + true, // boolean climbUnversionedParents + SVNDepth.FILES, // SVNDepth depth + false, // boolean includeIgnored + true); // boolean makeParents + + // previous added dir, should not appear in list + File directory = null; + List<String> expResult = new ArrayList<String>(3); + expResult.add("regions"); + expResult.add("scripts"); + expResult.add("simulations"); + List<String> result = vcs.getFileList(directory); + Assert.assertEquals(expResult, result); + } + /** + * Test of getFileList method, of class VCSSVN. + * + * Add some dir on remote repo. + * + * @throws VCSException + * @throws SVNException + */ + @Test + public void testGetFileList3() throws VCSException, SVNException { + + // log + if(log.isInfoEnabled()) { + log.info("testGetFileList3()"); + } + + // checkout current trunk + vcs.checkout(null, true); + + // now, make a modification, on REMOTE repo + SVNURL svnURL = SVNURL.parseURIDecoded("file://" + remoteRepo.getAbsolutePath()); + SVNURL svnURLNewDir = svnURL.appendPath("isis-fish-data", false) + .appendPath("trunk", false) + .appendPath("test", false); + SVNClientManager svnManager = SVNClientManager.newInstance(); + svnManager.getCommitClient().doMkDir(new SVNURL[]{svnURLNewDir}, "add test dir"); + + // previous added dir, should appear in list + File directory = null; + List<String> expResult = new ArrayList<String>(3); + expResult.add("regions"); + expResult.add("scripts"); + expResult.add("simulations"); + expResult.add("test"); + List<String> result = vcs.getFileList(directory); + Assert.assertEquals(expResult, result); + } + + /** * Test of getUpdatedFile method, of class VCSSVN. + * @throws VCSException + * @throws IOException + * @throws SVNException */ - //@Test - public void testgetUpdatedFile() { - System.out.println("getUpdatedFile"); - List<File> expResult = null; - List<File> result = instance.getUpdatedFile(); - assertEquals(expResult, result); + @Test + public void testGetUpdatedFile() throws VCSException, IOException, SVNException { + + // log + if(log.isInfoEnabled()) { + log.info("testGetUpdatedFile()"); + } + + List<File> expResult = new ArrayList<File>(); + expResult.add(new File(vcs.getLocalRepository().getAbsolutePath() + File.separator + "test")); + expResult.add(vcs.getLocalRepository()); + + // checkout current trunk + vcs.checkout(null, true); + + // now, make a modification, on REMOTE repo + SVNURL svnURL = SVNURL.parseURIDecoded("file://" + remoteRepo.getAbsolutePath()); + SVNURL svnURLNewDir = svnURL.appendPath("isis-fish-data", false) + .appendPath("trunk", false) + .appendPath("test", false); + SVNClientManager svnManager = SVNClientManager.newInstance(); + svnManager.getCommitClient().doMkDir(new SVNURL[]{svnURLNewDir}, "add test dir"); + + List<File> result = vcs.getUpdatedFile(); + Assert.assertEquals(expResult, result); } + + /** + * Test of getUpdatedFile method, of class VCSSVN. + * @throws VCSException + * @throws IOException + * @throws SVNException + */ + @Test + public void testGetUpdatedFileEmptyResult() throws VCSException, IOException, SVNException { + + // log + if(log.isInfoEnabled()) { + log.info("testGetUpdatedFile()"); + } + List<File> expResult = new ArrayList<File>(); + + // checkout current trunk + vcs.checkout(null, true); + + List<File> result = vcs.getUpdatedFile(); + Assert.assertEquals(expResult, result); + + } + /** - * Test of haveUpdate method, of class VCSSVN. + * Ask if there are some new or modified files on server. + * + * @throws VCSException + * @throws SVNException */ - //@Test - public void testhaveUpdate() { - System.out.println("haveUpdate"); - boolean expResult = false; - boolean result = instance.haveUpdate(); - assertEquals(expResult, result); + @Test + public void testHaveUpdate() throws VCSException, SVNException { + + // log + if(log.isInfoEnabled()) { + log.info("testHaveUpdate()"); + } + + // checkout current trunk + vcs.checkout(null, true); + + // now, make a modification, on REMOTE repo + SVNURL svnURL = SVNURL.parseURIDecoded("file://" + remoteRepo.getAbsolutePath()); + SVNURL svnURLNewDir = svnURL.appendPath("isis-fish-data", false) + .appendPath("trunk", false) + .appendPath("test", false); + SVNClientManager svnManager = SVNClientManager.newInstance(); + svnManager.getCommitClient().doMkDir(new SVNURL[]{svnURLNewDir}, "add test dir"); + + boolean result = vcs.haveUpdate(); + Assert.assertTrue(result); } + + /** + * Ask if there are some new or modified files on server. + * + * @throws VCSException + * @throws SVNException + */ + @Test + public void testHaveNoUpdate() throws VCSException, SVNException { + + // log + if(log.isInfoEnabled()) { + log.info("testHaveNoUpdate()"); + } + // checkout current trunk + vcs.checkout(null, true); + + boolean result = vcs.haveUpdate(); + Assert.assertFalse(result); + } + /** * Test of isConnected method, of class VCSSVN. */ - //@Test - public void testisConnected() { - System.out.println("isConnected"); - boolean expResult = true; - boolean result = instance.isConnected(); - assertEquals(expResult, result); + @Test + public void testIsConnected() { + + // log + if(log.isInfoEnabled()) { + log.info("testIsConnected()"); + } + + boolean result = vcs.isConnected(); + Assert.assertTrue(result); } /** * Test of isOnRemote method, of class VCSSVN. + * @throws VCSException */ - //@Test - public void testisOnRemote() throws Exception { - System.out.println("isOnRemote"); + @Test + public void testIsOnRemote() throws VCSException { + + // log + if(log.isInfoEnabled()) { + log.info("testIsOnRemote()"); + } + + vcs.checkout(null, false); + File file = null; - boolean expResult = false; - boolean result = instance.isOnRemote(file); - assertEquals(expResult, result); + boolean result = vcs.isOnRemote(file); + Assert.assertTrue(result); } + + /** + * Test of isOnRemote method, of class VCSSVN. + * @throws VCSException + */ + @Test + public void testIsOnRemote2() throws VCSException { + + // log + if(log.isInfoEnabled()) { + log.info("testIsOnRemote2()"); + } + vcs.checkout(null, false); + + File file = new File(vcs.getLocalRepository() + File.separator + "scripts" + File.separator + "version.txt"); + boolean result = vcs.isOnRemote(file); + Assert.assertTrue(result); + } + /** - * Test of isTag method, of class VCSSVN. + * Test of isOnRemote method, of class VCSSVN. + * @throws VCSException + * @throws SVNException */ - //@Test - public void testisTag() throws Exception { - System.out.println("isTag"); - { - VersionNumber version = new VersionNumber(3,1,0); - boolean expResult = true; - boolean result = instance.isTag(version); - assertEquals(expResult, result); + @Test + public void testIsOnRemote3() throws VCSException, SVNException { + + // log + if(log.isInfoEnabled()) { + log.info("testIsOnRemote3()"); } - { - VersionNumber version = new VersionNumber(3,2,0); - boolean expResult = false; - boolean result = instance.isTag(version); - assertEquals(expResult, result); + + vcs.checkout(null, false); + + // now, make a modification, on REMOTE repo + SVNURL svnURL = SVNURL.parseURIDecoded("file://" + remoteRepo.getAbsolutePath()); + SVNURL svnURLNewDir = svnURL.appendPath("isis-fish-data", false) + .appendPath("trunk", false) + .appendPath("test", false); + SVNClientManager svnManager = SVNClientManager.newInstance(); + svnManager.getCommitClient().doMkDir(new SVNURL[]{svnURLNewDir}, "add test dir"); + + File file = new File(vcs.getLocalRepository() + File.separator + "test"); + boolean result = vcs.isOnRemote(file); + Assert.assertTrue(result); + } + + /** + * Test of isOnRemote method, of class VCSSVN. + * @throws VCSException + * @throws SVNException + */ + @Test + public void testIsOnRemote4() throws VCSException, SVNException { + + // log + if(log.isInfoEnabled()) { + log.info("testIsOnRemote4()"); } + + vcs.checkout(null, false); + + // now, make a modification, on REMOTE repo + SVNURL svnURL = SVNURL.parseURIDecoded("file://" + remoteRepo.getAbsolutePath()); + SVNURL svnURLNewDir = svnURL.appendPath("isis-fish-data", false) + .appendPath("trunk", false) + .appendPath("scripts", false); + SVNClientManager svnManager = SVNClientManager.newInstance(); + svnManager.getCommitClient().doDelete(new SVNURL[]{svnURLNewDir}, "del scripts dir"); + + File file = new File(vcs.getLocalRepository() + File.separator + "scripts"); + boolean result = vcs.isOnRemote(file); + Assert.assertFalse(result); } + + /** + * Test of isOnRemote method, of class VCSSVN. + * @throws VCSException + * @throws SVNException + * @throws IOException + */ + @Test + public void testIsOnRemote5() throws VCSException, SVNException, IOException { + + // log + if(log.isInfoEnabled()) { + log.info("testIsOnRemote5()"); + } + vcs.checkout(null, false); + + // modif on local repo + File file = new File(vcs.getLocalRepository() + File.separator + "test.txt"); + FileUtil.writeString(file, "name = test1"); + SVNClientManager svnManager = SVNClientManager.newInstance(); + svnManager.getWCClient().doAdd( + file, // File path + true, // boolean force + false, // boolean mkdir + true, // boolean climbUnversionedParents + SVNDepth.FILES, // SVNDepth depth + false, // boolean includeIgnored + true); // boolean makeParents + + boolean result = vcs.isOnRemote(file); + Assert.assertFalse(result); + } + /** + * Test of isTag method, of class VCSSVN. + * @throws VCSException + */ + @Test + public void testIsTag() throws VCSException { + + // log + if(log.isInfoEnabled()) { + log.info("testGetDiff()"); + } + + VersionNumber version = new VersionNumber(3,1,0); + boolean expResult = true; + boolean result = vcs.isTag(version); + Assert.assertEquals(expResult, result); + + version = new VersionNumber(3,2,0); + expResult = false; + result = vcs.isTag(version); + Assert.assertEquals(expResult, result); + } + + /** * Test of isUpToDate method, of class VCSSVN. + * @throws VCSException */ - //@Test - public void testisUpToDate() throws Exception { - System.out.println("isUpToDate"); + @Test + public void testIsUpToDate() throws VCSException { + + // log + if(log.isInfoEnabled()) { + log.info("testIsUpToDate()"); + } + + vcs.checkout(null, false); + File file = null; - boolean expResult = false; - boolean result = instance.isUpToDate(file); - assertEquals(expResult, result); + boolean result = vcs.isUpToDate(file); + Assert.assertTrue(result); + } + + /** + * Test of isUpToDate method, of class VCSSVN. + * @throws VCSException + * @throws IOException + * @throws SVNException + */ + @Test + public void testIsUpToDate2() throws VCSException, IOException, SVNException { + + // log + if(log.isInfoEnabled()) { + log.info("testIsUpToDate2()"); + } + // chechout + vcs.checkout(null, false); + + // modif on local repo + File file = new File(vcs.getLocalRepository() + File.separator + "test.txt"); + FileUtil.writeString(file, "name = test1"); + SVNClientManager svnManager = SVNClientManager.newInstance(); + svnManager.getWCClient().doAdd( + file, // File path + true, // boolean force + false, // boolean mkdir + true, // boolean climbUnversionedParents + SVNDepth.FILES, // SVNDepth depth + false, // boolean includeIgnored + true); // boolean makeParents + + boolean result = vcs.isUpToDate(file); + Assert.assertFalse(result); + + } + + /** + * Test of isUpToDate method, of class VCSSVN. + * @throws VCSException + * @throws IOException + * @throws SVNException + */ + @Test + public void testIsUpToDate3() throws VCSException, IOException, SVNException { + + // log + if(log.isInfoEnabled()) { + log.info("testIsUpToDate3()"); + } + + // chechout + vcs.checkout(null, false); + + // now, make a modification, on REMOTE repo + SVNURL svnURL = SVNURL.parseURIDecoded("file://" + remoteRepo.getAbsolutePath()); + SVNURL svnURLNewDir = svnURL.appendPath("isis-fish-data", false) + .appendPath("trunk", false) + .appendPath("test", false); + SVNClientManager svnManager = SVNClientManager.newInstance(); + svnManager.getCommitClient().doMkDir(new SVNURL[]{svnURLNewDir}, "add test dir"); + + File file = new File(vcs.getLocalRepository() + File.separator + "test"); + boolean result = vcs.isUpToDate(file); + Assert.assertFalse(result); + + } } \ No newline at end of file
participants (1)
-
chatellier@users.labs.libre-entreprise.org