001/* 002 * Licensed to the Apache Software Foundation (ASF) under one 003 * or more contributor license agreements. See the NOTICE file 004 * distributed with this work for additional information 005 * regarding copyright ownership. The ASF licenses this file 006 * to you under the Apache License, Version 2.0 (the 007 * "License"); you may not use this file except in compliance 008 * with the License. You may obtain a copy of the License at 009 * 010 * http://www.apache.org/licenses/LICENSE-2.0 011 * 012 * Unless required by applicable law or agreed to in writing, 013 * software distributed under the License is distributed on an 014 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 015 * KIND, either express or implied. See the License for the 016 * specific language governing permissions and limitations 017 * under the License. 018 */ 019package org.apache.maven.scm.provider.svn.svnexe.command.remoteinfo; 020 021import java.util.HashMap; 022import java.util.Map; 023 024import org.apache.commons.lang3.StringUtils; 025import org.apache.maven.scm.CommandParameters; 026import org.apache.maven.scm.ScmException; 027import org.apache.maven.scm.ScmFileSet; 028import org.apache.maven.scm.command.remoteinfo.AbstractRemoteInfoCommand; 029import org.apache.maven.scm.command.remoteinfo.RemoteInfoScmResult; 030import org.apache.maven.scm.provider.ScmProviderRepository; 031import org.apache.maven.scm.provider.svn.command.SvnCommand; 032import org.apache.maven.scm.provider.svn.repository.SvnScmProviderRepository; 033import org.apache.maven.scm.provider.svn.svnexe.command.SvnCommandLineUtils; 034import org.apache.maven.scm.util.AbstractConsumer; 035import org.codehaus.plexus.util.cli.CommandLineException; 036import org.codehaus.plexus.util.cli.CommandLineUtils; 037import org.codehaus.plexus.util.cli.Commandline; 038 039/** 040 * @author Olivier Lamy 041 * @since 1.6 042 */ 043public class SvnRemoteInfoCommand extends AbstractRemoteInfoCommand implements SvnCommand { 044 @Override 045 public RemoteInfoScmResult executeRemoteInfoCommand( 046 ScmProviderRepository repository, ScmFileSet fileSet, CommandParameters parameters) throws ScmException { 047 048 String url = ((SvnScmProviderRepository) repository).getUrl(); 049 // use a default svn layout, url is here http://svn.apache.org/repos/asf/maven/maven-3/trunk 050 // so as we presume we have good users using standard svn layout, we calculate tags and branches url 051 url = StringUtils.stripEnd(url, "/"); 052 int idx = url.lastIndexOf("/"); 053 String baseUrl = url.substring(0, idx); 054 055 Commandline cl = SvnCommandLineUtils.getBaseSvnCommandLine( 056 fileSet == null ? null : fileSet.getBasedir(), (SvnScmProviderRepository) repository); 057 058 cl.createArg().setValue("ls"); 059 060 cl.createArg().setValue(baseUrl + "/tags" + "@"); 061 062 CommandLineUtils.StringStreamConsumer stderr = new CommandLineUtils.StringStreamConsumer(); 063 064 LsConsumer consumer = new LsConsumer(baseUrl + "/tags"); 065 066 int exitCode = 0; 067 068 Map<String, String> tagsInfos = null; 069 070 try { 071 exitCode = SvnCommandLineUtils.execute(cl, consumer, stderr); 072 tagsInfos = consumer.infos; 073 074 } catch (CommandLineException ex) { 075 throw new ScmException("Error while executing svn command.", ex); 076 } 077 078 if (exitCode != 0) { 079 return new RemoteInfoScmResult(cl.toString(), "The svn command failed.", stderr.getOutput(), false); 080 } 081 082 cl = SvnCommandLineUtils.getBaseSvnCommandLine( 083 fileSet == null ? null : fileSet.getBasedir(), (SvnScmProviderRepository) repository); 084 085 cl.createArg().setValue("ls"); 086 087 cl.createArg().setValue(baseUrl + "/branches" + "@"); 088 089 stderr = new CommandLineUtils.StringStreamConsumer(); 090 091 consumer = new LsConsumer(baseUrl + "/branches"); 092 093 Map<String, String> branchesInfos = null; 094 095 try { 096 exitCode = SvnCommandLineUtils.execute(cl, consumer, stderr); 097 branchesInfos = consumer.infos; 098 099 } catch (CommandLineException ex) { 100 throw new ScmException("Error while executing svn command.", ex); 101 } 102 103 if (exitCode != 0) { 104 return new RemoteInfoScmResult(cl.toString(), "The svn command failed.", stderr.getOutput(), false); 105 } 106 107 return new RemoteInfoScmResult(cl.toString(), branchesInfos, tagsInfos); 108 } 109 110 public boolean remoteUrlExist(ScmProviderRepository repository, CommandParameters parameters) throws ScmException { 111 String url = ((SvnScmProviderRepository) repository).getUrl(); 112 113 Commandline cl = SvnCommandLineUtils.getBaseSvnCommandLine(null, (SvnScmProviderRepository) repository); 114 115 cl.createArg().setValue("ls"); 116 117 cl.createArg().setValue(url + "@"); 118 119 CommandLineUtils.StringStreamConsumer stderr = new CommandLineUtils.StringStreamConsumer(); 120 121 LsConsumer consumer = new LsConsumer(url); 122 123 int exitCode = 0; 124 125 try { 126 exitCode = SvnCommandLineUtils.execute(cl, consumer, stderr); 127 } catch (CommandLineException ex) { 128 throw new ScmException("Error while executing svn command.", ex); 129 } 130 131 if (exitCode != 0) { 132 String output = stderr.getOutput(); 133 // olamy: a bit ugly but.... 134 // trying to parse error from svn cli which indicate no remote path 135 if (output.contains("W160013") || output.contains("svn: URL")) { 136 return false; 137 } 138 throw new ScmException(cl + ".The svn command failed:" + stderr.getOutput()); 139 } 140 141 return true; 142 } 143 144 private static class LsConsumer extends AbstractConsumer { 145 Map<String, String> infos = new HashMap<>(); 146 147 String url; 148 149 LsConsumer(String url) { 150 this.url = url; 151 } 152 153 public void consumeLine(String s) { 154 infos.put(StringUtils.stripEnd(s, "/"), url + "/" + s); 155 } 156 157 Map<String, String> getInfos() { 158 return infos; 159 } 160 } 161}