View Javadoc
1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one
3    * or more contributor license agreements.  See the NOTICE file
4    * distributed with this work for additional information
5    * regarding copyright ownership.  The ASF licenses this file
6    * to you under the Apache License, Version 2.0 (the
7    * "License"); you may not use this file except in compliance
8    * with the License.  You may obtain a copy of the License at
9    *
10   *   http://www.apache.org/licenses/LICENSE-2.0
11   *
12   * Unless required by applicable law or agreed to in writing,
13   * software distributed under the License is distributed on an
14   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15   * KIND, either express or implied.  See the License for the
16   * specific language governing permissions and limitations
17   * under the License.
18   */
19  package org.apache.maven.scm.provider.svn.svnexe.command.remoteinfo;
20  
21  import java.util.HashMap;
22  import java.util.Map;
23  
24  import org.apache.commons.lang3.StringUtils;
25  import org.apache.maven.scm.CommandParameters;
26  import org.apache.maven.scm.ScmException;
27  import org.apache.maven.scm.ScmFileSet;
28  import org.apache.maven.scm.command.remoteinfo.AbstractRemoteInfoCommand;
29  import org.apache.maven.scm.command.remoteinfo.RemoteInfoScmResult;
30  import org.apache.maven.scm.provider.ScmProviderRepository;
31  import org.apache.maven.scm.provider.svn.command.SvnCommand;
32  import org.apache.maven.scm.provider.svn.repository.SvnScmProviderRepository;
33  import org.apache.maven.scm.provider.svn.svnexe.command.SvnCommandLineUtils;
34  import org.apache.maven.scm.util.AbstractConsumer;
35  import org.codehaus.plexus.util.cli.CommandLineException;
36  import org.codehaus.plexus.util.cli.CommandLineUtils;
37  import org.codehaus.plexus.util.cli.Commandline;
38  
39  /**
40   * @author Olivier Lamy
41   * @since 1.6
42   */
43  public class SvnRemoteInfoCommand extends AbstractRemoteInfoCommand implements SvnCommand {
44      @Override
45      public RemoteInfoScmResult executeRemoteInfoCommand(
46              ScmProviderRepository repository, ScmFileSet fileSet, CommandParameters parameters) throws ScmException {
47  
48          String url = ((SvnScmProviderRepository) repository).getUrl();
49          // use a default svn layout, url is here http://svn.apache.org/repos/asf/maven/maven-3/trunk
50          // so as we presume we have good users using standard svn layout, we calculate tags and branches url
51          url = StringUtils.stripEnd(url, "/");
52          int idx = url.lastIndexOf("/");
53          String baseUrl = url.substring(0, idx);
54  
55          Commandline cl = SvnCommandLineUtils.getBaseSvnCommandLine(
56                  fileSet == null ? null : fileSet.getBasedir(), (SvnScmProviderRepository) repository);
57  
58          cl.createArg().setValue("ls");
59  
60          cl.createArg().setValue(baseUrl + "/tags" + "@");
61  
62          CommandLineUtils.StringStreamConsumer stderr = new CommandLineUtils.StringStreamConsumer();
63  
64          LsConsumer consumer = new LsConsumer(baseUrl + "/tags");
65  
66          int exitCode = 0;
67  
68          Map<String, String> tagsInfos = null;
69  
70          try {
71              exitCode = SvnCommandLineUtils.execute(cl, consumer, stderr);
72              tagsInfos = consumer.infos;
73  
74          } catch (CommandLineException ex) {
75              throw new ScmException("Error while executing svn command.", ex);
76          }
77  
78          if (exitCode != 0) {
79              return new RemoteInfoScmResult(cl.toString(), "The svn command failed.", stderr.getOutput(), false);
80          }
81  
82          cl = SvnCommandLineUtils.getBaseSvnCommandLine(
83                  fileSet == null ? null : fileSet.getBasedir(), (SvnScmProviderRepository) repository);
84  
85          cl.createArg().setValue("ls");
86  
87          cl.createArg().setValue(baseUrl + "/branches" + "@");
88  
89          stderr = new CommandLineUtils.StringStreamConsumer();
90  
91          consumer = new LsConsumer(baseUrl + "/branches");
92  
93          Map<String, String> branchesInfos = null;
94  
95          try {
96              exitCode = SvnCommandLineUtils.execute(cl, consumer, stderr);
97              branchesInfos = consumer.infos;
98  
99          } 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 }