package com.perforce.maven.scm.provider.p4.util; import java.io.File; import java.io.FileNotFoundException; import java.io.IOException; import java.net.InetAddress; import java.util.ArrayList; import java.util.Arrays; import java.util.HashSet; import java.util.List; import org.apache.maven.scm.ScmException; import org.apache.maven.scm.ScmFileSet; import org.apache.maven.scm.ScmTag; import org.apache.maven.scm.ScmVersion; import org.codehaus.plexus.util.ReaderFactory; import org.codehaus.plexus.util.StringUtils; import org.codehaus.plexus.util.xml.pull.XmlPullParserException; import com.perforce.maven.scm.provider.p4.repository.P4ScmProviderRepository; import com.perforce.maven.scm.provider.p4.settings.Settings; import com.perforce.maven.scm.provider.p4.settings.io.xpp3.P4MavenXpp3Reader; import com.perforce.p4java.client.IClient; import com.perforce.p4java.core.file.FileSpecBuilder; import com.perforce.p4java.core.file.IFileSpec; public class P4Utils { private P4Utils() { } /** * Gets the canonical repo path. * * @param repoPath the repo path * @return the canonical repo path */ public static String getCanonicalRepoPath( String repoPath ) { if ( repoPath == null ) { return null; } if ( repoPath.endsWith( "/" ) ) { repoPath += "..."; } else if ( !repoPath.endsWith( "/..." ) ) { repoPath += "/..."; } if ( repoPath.contains( " " ) ) { repoPath = "\"" + repoPath + "\""; } return repoPath; } /** * Perforce wildcards expansion. * * @param filePath the file path * @return the string */ public static String encodeWildcards( String filePath ) { String path = new String(); if ( filePath != null ) { path = filePath.replaceAll( "%", "%25" ).replaceAll( "\\*", "%2A" ).replaceAll( "#", "%23" ).replaceAll( "@", "%40" ); } return path; } /** * Checks if is empty. * * @param value the value * @return true, if is empty */ public static boolean isEmpty( String value ) { if ( value == null || value.trim().length() == 0 ) { return true; } return false; } /** * Gets the repo location. * * @param path the path * @return the repo location */ public static String getRepoLocation( IClient client, File localFile ) throws ScmException { try { List<IFileSpec> fileSpecs = client.where( FileSpecBuilder.makeFileSpecList( encodeWildcards( localFile.getAbsolutePath() ) ) ); for ( IFileSpec fileSpec : fileSpecs ) { if ( !P4Utils.isEmpty( fileSpec.getDepotPathString() ) ) { return fileSpec.getDepotPathString(); } } } catch ( Exception e ) { throw new ScmException( e.getLocalizedMessage(), e ); } return null; } /** * Generate a Perforce client workspace name. * * @return the string * @throws IOException */ public static String generateClientName( File basedir ) throws IOException { String username = System.getProperty( "user.name" ); String hostname = InetAddress.getLocalHost().getHostName(); String path = encodeWildcards( basedir.getCanonicalPath().replaceAll( "[/ ~]", "-" ).replaceAll( ",", "" ) ); return username + "-" + hostname + "-MavenSCM-" + path; } public static String scmVersion2SuffixString( ScmVersion version ) { String versionSuffix = ""; if ( version != null && !P4Utils.isEmpty( version.getName() ) ) { versionSuffix = "@" + version.getName(); } return versionSuffix; } /** * Convert ScmFileSet to List<IFileSpec> for * * @param fileSet * @return * @throws ScmException */ public static List<IFileSpec> scmFileSet2P4FileSpecsWithNop4WildCard( ScmFileSet fileSet, ScmVersion version ) throws ScmException { String versionSuffix = scmVersion2SuffixString( version ); List<IFileSpec> fileSpecs = new ArrayList<IFileSpec>(); try { List<File> fileList = fileSet.getFileList(); if ( fileList != null ) { HashSet<String> filePaths = new HashSet<String>(); for ( File file : fileList ) { if ( ".".equals( file.getPath() ) ) { // ignore child path "." since it is the same as parent dir // this happens when issue mvn scm:command from command line continue; } if ( !file.isAbsolute() ) { // It is assumed that ScmFileSet does validate its fileList which must be relative to its // basedir file = new File( fileSet.getBasedir(), file.getPath() ); } filePaths.add( P4Utils.encodeWildcards( file.getCanonicalPath() + versionSuffix ) ); } if ( !filePaths.isEmpty() ) { fileSpecs = FileSpecBuilder.makeFileSpecList( filePaths.toArray( new String[filePaths.size()] ) ); } } } catch ( IOException e ) { throw new ScmException( e.getLocalizedMessage(), e ); } return fileSpecs; } public static List<IFileSpec> scmFileSet2P4FileSpecsWithNoP4WildCard( ScmFileSet fileSet ) throws ScmException { return scmFileSet2P4FileSpecsWithNop4WildCard( fileSet, null ); } public static List<IFileSpec> scmFileSet2P4FileSpecs( ScmFileSet fileSet, ScmVersion version ) throws ScmException { List<IFileSpec> fileSpecs = scmFileSet2P4FileSpecsWithNop4WildCard( fileSet, version ); if ( fileSpecs.isEmpty() ) { if ( P4Utils.isEmpty( fileSet.getIncludes() ) && P4Utils.isEmpty( fileSet.getExcludes() ) ) { String versionSuffix = scmVersion2SuffixString( version ); if ( isEmpty( versionSuffix ) ) { versionSuffix = "/..."; } String filePath = fileSet.getBasedir().getAbsolutePath() + versionSuffix; // very hacky if ( version instanceof ScmTag ) { filePath = "@" + version.getName(); } fileSpecs = FileSpecBuilder.makeFileSpecList( new String[] { filePath } ); } } return fileSpecs; } public static List<IFileSpec> scmFileSet2P4FileSpecs( ScmFileSet fileSet ) throws ScmException { return scmFileSet2P4FileSpecs( fileSet, null ); } // ////////////////////////////////////////////////////////////////////////////////////////////////////////// private static final String P4MAVEN_SETTINGS_FILENAME = "p4maven-settings.xml"; private static final File DEFAULT_SETTINGS_DIRECTORY = new File( System.getProperty( "user.home" ), ".scm" ); private static File settingsDirectory = DEFAULT_SETTINGS_DIRECTORY; private static Settings settings; public static synchronized Settings getSettings() { if ( settings == null ) { settings = readSettings(); } return settings; } private static Settings readSettings() { File settingsFile = getSettingsFile(); Settings settings = new Settings(); if ( settingsFile.exists() ) { P4MavenXpp3Reader reader = new P4MavenXpp3Reader(); try { settings = reader.read( ReaderFactory.newXmlReader( settingsFile ) ); } catch ( FileNotFoundException e ) { // nop } catch ( IOException e ) { // nop } catch ( XmlPullParserException e ) { String message = settingsFile.getAbsolutePath() + " isn't well formed. SKIPPED." + e.getMessage(); System.err.println( message ); } } // override if found from system properties String jobs = System.getProperty( P4ScmProviderRepository.P4_JOBS_PROPERTY ); if ( jobs != null ) { settings.setJobs( jobs ); } String clientName = System.getProperty( P4ScmProviderRepository.P4_CLIENT_PROPERTY ); if ( clientName != null ) { settings.setClientName( clientName ); } String lockTag = System.getProperty( P4ScmProviderRepository.P4_LOCK_TAG_PROPERTY ); if ( lockTag != null ) { settings.setLockTag( "true".equals( lockTag ) ); } String charset = System.getProperty( P4ScmProviderRepository.P4_CHARSET_PROPERTY ); if ( charset != null ) { settings.setCharset( charset ); } return settings; } public static List<String> getJobs() { String jobs = getSettings().getJobs(); if ( jobs == null ) { jobs = ""; } String[] tokens = StringUtils.split( jobs ); return new ArrayList<String>( Arrays.asList( tokens ) ); } public static File getSettingsFile() { return new File( settingsDirectory, P4MAVEN_SETTINGS_FILENAME ); } public static void setSettingsDirectory( File directory ) { settingsDirectory = directory; } }
# | Change | User | Description | Committed | |
---|---|---|---|---|---|
#16 | 9519 | dantran | folder rename to match with its artifactId | ||
#15 | 9514 | dantran |
- Remove support to pick up p4port and its credential from ENV and System properties. These setttings has no use since Maven requires user to provide the required URL which has both p4port and credential. Also user can always fall back to settings.xml to store credential - Rewrite URL parser and also support password as part of URL - TCK test now has default URL and its credential is store under settings.xml - User can also issue her how scmTckUrl system properties ( to be doc as part of maven site) |
||
#14 | 9513 | dantran | add provider doc, deploy site:jar, support external charset config | ||
#13 | 9498 | dantran |
- Setup Maven site for documetation - Implement ~/m2/p4maven-settings.xml to store external config overridable by system properties. All global settings now can be retrieved va P4Utils |
||
#12 | 9477 | dantran | add logger, prepare the next release | ||
#11 | 9471 | dantran |
- cleanup diff command - simplify branch command and full compliant with maven-scm-test - add checkout with branch - add repo's path as client manager lookup key in addition to p4port and rootdir so that we can handle mutiple clients on the same rootdir |
||
#10 | 9451 | dantran | Discover current client | ||
#9 | 9444 | dantran | Handle ScmFileSet's fileList has absolute paths | ||
#8 | 9442 | dantran | Handle ScmFileSet which has a file named "." | ||
#7 | 9441 | dantran | discover existing client, so that we dont need pass in this name via system property during release:prepare | ||
#6 | 9423 | dantran | get all test to use the same setup, handle checkout with tag, need to revisit how we handle ScmVersion | ||
#5 | 9422 | dantran | add update, changelog TCK | ||
#4 | 9342 | dantran | Add CheckIn TCK | ||
#3 | 9290 | dantran | Introduce the reusable P4Utils.scmFileSet2P4FileSpecs util, and have edit and checkin command to use it | ||
#2 | 9259 | dantran |
hookup with maven-scm-test. Pickup user/password from system properties |
||
#1 | 9250 | dantran | caching client across mutiple commands |