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 045 private final boolean interactive; 046 047 public SvnRemoteInfoCommand(boolean interactive) { 048 this.interactive = interactive; 049 } 050 051 @Override 052 public RemoteInfoScmResult executeRemoteInfoCommand( 053 ScmProviderRepository repository, ScmFileSet fileSet, CommandParameters parameters) throws ScmException { 054 055 String url = ((SvnScmProviderRepository) repository).getUrl(); 056 // use a default svn layout, url is here http://svn.apache.org/repos/asf/maven/maven-3/trunk 057 // so as we presume we have good users using standard svn layout, we calculate tags and branches url 058 url = StringUtils.stripEnd(url, "/"); 059 int idx = url.lastIndexOf("/"); 060 String baseUrl = url.substring(0, idx); 061 062 Commandline cl = SvnCommandLineUtils.getBaseSvnCommandLine( 063 fileSet == null ? null : fileSet.getBasedir(), (SvnScmProviderRepository) repository, interactive); 064 065 cl.createArg().setValue("ls"); 066 067 cl.createArg().setValue(baseUrl + "/tags" + "@"); 068 069 CommandLineUtils.StringStreamConsumer stderr = new CommandLineUtils.StringStreamConsumer(); 070 071 LsConsumer consumer = new LsConsumer(baseUrl + "/tags"); 072 073 int exitCode = 0; 074 075 Map<String, String> tagsInfos = null; 076 077 try { 078 exitCode = SvnCommandLineUtils.execute(cl, consumer, stderr); 079 tagsInfos = consumer.infos; 080 081 } catch (CommandLineException ex) { 082 throw new ScmException("Error while executing svn command.", ex); 083 } 084 085 if (exitCode != 0) { 086 return new RemoteInfoScmResult(cl.toString(), "The svn command failed.", stderr.getOutput(), false); 087 } 088 089 cl = SvnCommandLineUtils.getBaseSvnCommandLine( 090 fileSet == null ? null : fileSet.getBasedir(), (SvnScmProviderRepository) repository, interactive); 091 092 cl.createArg().setValue("ls"); 093 094 cl.createArg().setValue(baseUrl + "/branches" + "@"); 095 096 stderr = new CommandLineUtils.StringStreamConsumer(); 097 098 consumer = new LsConsumer(baseUrl + "/branches"); 099 100 Map<String, String> branchesInfos = null; 101 102 try { 103 exitCode = SvnCommandLineUtils.execute(cl, consumer, stderr); 104 branchesInfos = consumer.infos; 105 106 } catch (CommandLineException ex) { 107 throw new ScmException("Error while executing svn command.", ex); 108 } 109 110 if (exitCode != 0) { 111 return new RemoteInfoScmResult(cl.toString(), "The svn command failed.", stderr.getOutput(), false); 112 } 113 114 return new RemoteInfoScmResult(cl.toString(), branchesInfos, tagsInfos); 115 } 116 117 public boolean remoteUrlExist(ScmProviderRepository repository, CommandParameters parameters) throws ScmException { 118 String url = ((SvnScmProviderRepository) repository).getUrl(); 119 120 Commandline cl = 121 SvnCommandLineUtils.getBaseSvnCommandLine(null, (SvnScmProviderRepository) repository, interactive); 122 123 cl.createArg().setValue("ls"); 124 125 cl.createArg().setValue(url + "@"); 126 127 CommandLineUtils.StringStreamConsumer stderr = new CommandLineUtils.StringStreamConsumer(); 128 129 LsConsumer consumer = new LsConsumer(url); 130 131 int exitCode = 0; 132 133 try { 134 exitCode = SvnCommandLineUtils.execute(cl, consumer, stderr); 135 } catch (CommandLineException ex) { 136 throw new ScmException("Error while executing svn command.", ex); 137 } 138 139 if (exitCode != 0) { 140 String output = stderr.getOutput(); 141 // olamy: a bit ugly but.... 142 // trying to parse error from svn cli which indicate no remote path 143 if (output.contains("W160013") || output.contains("svn: URL")) { 144 return false; 145 } 146 throw new ScmException(cl + ".The svn command failed:" + stderr.getOutput()); 147 } 148 149 return true; 150 } 151 152 private static class LsConsumer extends AbstractConsumer { 153 Map<String, String> infos = new HashMap<>(); 154 155 String url; 156 157 LsConsumer(String url) { 158 this.url = url; 159 } 160 161 public void consumeLine(String s) { 162 infos.put(StringUtils.stripEnd(s, "/"), url + "/" + s); 163 } 164 165 Map<String, String> getInfos() { 166 return infos; 167 } 168 } 169}