/**
* Copyright (c) 2005-2017, KoLmafia development team
* http://kolmafia.sourceforge.net/
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* [1] Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* [2] Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
* [3] Neither the name "KoLmafia" nor the names of its contributors may
* be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION ) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE ) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
package net.sourceforge.kolmafia.textui.command;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import org.tmatesoft.svn.core.SVNException;
import org.tmatesoft.svn.core.SVNURL;
import net.sourceforge.kolmafia.KoLConstants;
import net.sourceforge.kolmafia.KoLmafia;
import net.sourceforge.kolmafia.RequestLogger;
import net.sourceforge.kolmafia.KoLConstants.MafiaState;
import net.sourceforge.kolmafia.svn.SVNManager;
public class SVNCommand
extends AbstractCommand
{
public SVNCommand()
{
this.usage = " checkout <svnurl> | update [<svnurl>] | list | delete <project> | sync - install/update/manage svn projects.";
}
@Override
public void run( final String cmd, final String parameters )
{
if ( parameters.trim().equals( "update" ) )
{
// user wants to update everything
SVNManager.doUpdate();
return;
}
if ( parameters.trim().equals( "sync" ) )
{
SVNManager.syncAll();
return;
}
if ( parameters.startsWith( "checkout" ) )
{
String params = parameters.substring( 8 ).trim();
if ( !params.startsWith( "svn:" ) && !params.startsWith( "http" ) )
{
KoLmafia.updateDisplay( MafiaState.ERROR, "You must specify a valid SVN url to update from. " + params );
return;
}
SVNURL repo;
try
{
repo = SVNURL.parseURIEncoded( params );
}
catch ( SVNException e1 )
{
KoLmafia.updateDisplay( MafiaState.ERROR, "Invalid SVN URL" );
return;
}
SVNManager.doCheckout( repo );
}
else if ( parameters.startsWith( "update" ) )
{
String params = parameters.substring( 6 ).trim();
// user might have supplied a URL
if ( params.startsWith( "svn:" ) || params.startsWith( "http" ) )
{
SVNURL repo;
try
{
repo = SVNURL.parseURIEncoded( params );
}
catch ( SVNException e1 )
{
KoLmafia.updateDisplay( MafiaState.ERROR, "Invalid SVN URL" );
return;
}
SVNManager.doUpdate( repo );
return;
}
// user might have supplied a local project name, see if there's a matching one.
String[] projects = KoLConstants.SVN_LOCATION.list();
if ( projects == null || projects.length == 0 )
{
RequestLogger.printLine( "No projects currently installed with SVN." );
return;
}
List<String> matches = getMatchingNames( projects, params );
if ( matches.size() > 1 )
{
RequestLogger.printList( matches );
RequestLogger.printLine();
KoLmafia.updateDisplay( MafiaState.ERROR, "[" + params + "] has too many matches." );
}
else if ( matches.size() == 1 )
{
SVNManager.doUpdate( matches.get( 0 ) );
}
else
{
KoLmafia.updateDisplay( MafiaState.ERROR, "No script matching " + params + " is currently installed." );
}
}
else if ( parameters.startsWith( "delete" ) )
{
String params = parameters.substring( 6 ).trim();
// user may specify a url
if ( params.startsWith( "svn:" ) || params.startsWith( "http" ) )
{
RequestLogger.printLine( "Specify a project (see \"svn list\"), not a URL.");
return;
}
// or user may specify a directory name
String[] projects = KoLConstants.SVN_LOCATION.list();
if ( projects == null || projects.length == 0 )
{
RequestLogger.printLine( "No projects currently installed with SVN." );
return;
}
List<String> matches = getMatchingNames( projects, params );
if ( matches.size() > 1 )
{
RequestLogger.printList( matches );
RequestLogger.printLine();
KoLmafia.updateDisplay( MafiaState.ERROR, "[" + params + "] has too many matches." );
}
else if ( matches.size() == 1 )
{
SVNManager.deleteInstalledProject( matches.get( 0 ) );
}
else
{
KoLmafia.updateDisplay( MafiaState.ERROR, "No script matching " + params + " is currently installed." );
}
}
else if ( parameters.startsWith( "list" ) )
{
String[] projects = KoLConstants.SVN_LOCATION.list();
if ( projects == null || projects.length == 0 )
RequestLogger.printLine( "No projects currently installed with SVN." );
else
RequestLogger.printList( Arrays.asList( projects ) );
}
else if ( parameters.startsWith( "decrement" ) || parameters.startsWith( "increment" ) ||
parameters.split( " " )[ 0 ].equals( "inc" ) || parameters.split( " " )[ 0 ].equals( "dec" ) )
{
String[] paramSplit = parameters.split( " " );
if ( paramSplit.length < 2 )
return;
String params = paramSplit[ 1 ].trim();
String[] projects = KoLConstants.SVN_LOCATION.list();
if ( projects == null || projects.length == 0 )
{
RequestLogger.printLine( "No projects currently installed with SVN." );
return;
}
List<String> matches = getMatchingNames( projects, params );
if ( matches.size() > 1 )
{
RequestLogger.printList( matches );
RequestLogger.printLine();
KoLmafia.updateDisplay( MafiaState.ERROR, "[" + params + "] has too many matches." );
}
else if ( matches.size() == 1 )
{
int amount = parameters.startsWith( "dec" ) ? -1 : 1;
SVNManager.incrementProject( matches.get( 0 ), amount );
}
else
{
KoLmafia.updateDisplay( MafiaState.ERROR, "No script matching " + params + " is currently installed." );
}
}
else if ( parameters.startsWith( "cleanup" ) )
{
SVNManager.doCleanup();
return;
}
}
/**
* One-off implementation of StringUtilities.getMatchingNames.
* <p>
* The issue with the StringUtilities version is that it assumes that the list of names to search against is
* canonicalized - i.e. all lower case. This cannot be done to directories since case matters in some environments.
*
* @param projects the array of currently-installed projects
* @param params the String input by the user to be matched
* @return a <code>List</code> of matches
*/
private static List<String> getMatchingNames( String[] projects, String params )
{
List<String> matches = new ArrayList<String>();
for ( String project : projects )
{
// exact matches return immediately, disregarding other substring matches
if ( project.equals( params ) )
{
return Arrays.asList( params );
}
if ( substringMatches( project, params ) )
{
matches.add( project );
}
}
return matches;
}
private static boolean substringMatches( final String source, final String substring )
{
if ( source == null )
{
return false;
}
if ( substring == null || substring.length() == 0 )
{
return true;
}
return source.contains( substring );
}
}