1 | package org.apache.continuum.scm; |
2 | |
3 | /* |
4 | * Licensed to the Apache Software Foundation (ASF) under one |
5 | * or more contributor license agreements. See the NOTICE file |
6 | * distributed with this work for additional information |
7 | * regarding copyright ownership. The ASF licenses this file |
8 | * to you under the Apache License, Version 2.0 (the |
9 | * "License"); you may not use this file except in compliance |
10 | * with the License. You may obtain a copy of the License at |
11 | * |
12 | * http://www.apache.org/licenses/LICENSE-2.0 |
13 | * |
14 | * Unless required by applicable law or agreed to in writing, |
15 | * software distributed under the License is distributed on an |
16 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY |
17 | * KIND, either express or implied. See the License for the |
18 | * specific language governing permissions and limitations |
19 | * under the License. |
20 | */ |
21 | |
22 | import java.io.File; |
23 | import java.io.IOException; |
24 | |
25 | import javax.annotation.Resource; |
26 | |
27 | import org.apache.commons.io.FileUtils; |
28 | import org.apache.commons.lang.StringUtils; |
29 | import org.apache.maven.scm.ScmException; |
30 | import org.apache.maven.scm.ScmFileSet; |
31 | import org.apache.maven.scm.ScmTag; |
32 | import org.apache.maven.scm.ScmVersion; |
33 | import org.apache.maven.scm.command.changelog.ChangeLogScmResult; |
34 | import org.apache.maven.scm.command.checkout.CheckOutScmResult; |
35 | import org.apache.maven.scm.command.update.UpdateScmResult; |
36 | import org.apache.maven.scm.manager.NoSuchScmProviderException; |
37 | import org.apache.maven.scm.manager.ScmManager; |
38 | import org.apache.maven.scm.repository.ScmRepository; |
39 | import org.apache.maven.scm.repository.ScmRepositoryException; |
40 | import org.springframework.stereotype.Service; |
41 | |
42 | /** |
43 | * @author <a href="mailto:trygvis@inamo.no">Trygve Laugstøl</a> |
44 | * @version $Id: DefaultContinuumScm.java 765340 2009-04-15 20:22:00Z evenisse $ |
45 | * @todo consider folding some of this into Maven SCM itself |
46 | */ |
47 | @Service("continuumScm") |
48 | public class DefaultContinuumScm |
49 | implements ContinuumScm |
50 | { |
51 | /** |
52 | * The Maven SCM manager to use. |
53 | */ |
54 | @Resource |
55 | private ScmManager scmManager; |
56 | |
57 | public CheckOutScmResult checkout( ContinuumScmConfiguration configuration ) |
58 | throws IOException, ScmException |
59 | { |
60 | ScmVersion scmVersion = getScmVersion( configuration ); |
61 | |
62 | // TODO: probably need to base this from a working directory in the main configuration |
63 | File workingDirectory = configuration.getWorkingDirectory(); |
64 | |
65 | ScmRepository repository = getScmRepository( configuration ); |
66 | |
67 | CheckOutScmResult result; |
68 | |
69 | // TODO: synchronizing *all* checkouts is unnecessary |
70 | synchronized ( this ) |
71 | { |
72 | if ( !workingDirectory.exists() ) |
73 | { |
74 | if ( !workingDirectory.mkdirs() ) |
75 | { |
76 | throw new IOException( "Could not make directory: " + workingDirectory.getAbsolutePath() ); |
77 | } |
78 | } |
79 | else |
80 | { |
81 | FileUtils.cleanDirectory( workingDirectory ); |
82 | } |
83 | |
84 | ScmFileSet fileSet = new ScmFileSet( workingDirectory ); |
85 | |
86 | result = scmManager.checkOut( repository, fileSet, scmVersion ); |
87 | } |
88 | return result; |
89 | } |
90 | |
91 | private ScmVersion getScmVersion( ContinuumScmConfiguration configuration ) |
92 | { |
93 | String tag = configuration.getTag(); |
94 | |
95 | ScmVersion scmVersion = null; |
96 | if ( tag != null ) |
97 | { |
98 | // TODO: differentiate between tag and branch? Allow for revision? |
99 | scmVersion = new ScmTag( tag ); |
100 | } |
101 | return scmVersion; |
102 | } |
103 | |
104 | public UpdateScmResult update( ContinuumScmConfiguration configuration ) |
105 | throws ScmException |
106 | { |
107 | ScmVersion scmVersion = getScmVersion( configuration ); |
108 | |
109 | File workingDirectory = configuration.getWorkingDirectory(); |
110 | if ( !workingDirectory.exists() ) |
111 | { |
112 | // TODO: maybe we could check it out - it seems we currently rely on Continuum figuring this out |
113 | throw new IllegalStateException( |
114 | "The working directory for the project doesn't exist " + "(" + workingDirectory.getAbsolutePath() + |
115 | ")." ); |
116 | } |
117 | |
118 | ScmRepository repository = getScmRepository( configuration ); |
119 | |
120 | // Some SCM provider requires additional system properties during update |
121 | if ( "starteam".equals( repository.getProvider() ) ) |
122 | { |
123 | // TODO: remove the use of system property - need a better way to pass provider specific configuration |
124 | |
125 | // Remove the clientspec name, so it will be recalculated between each command for each project |
126 | // instead of use the same for all projects |
127 | System.setProperty( "maven.scm.starteam.deleteLocal", "true" ); |
128 | } |
129 | |
130 | UpdateScmResult result; |
131 | |
132 | ScmFileSet fileSet = new ScmFileSet( workingDirectory ); |
133 | |
134 | // TODO: shouldn't need to synchronize this |
135 | synchronized ( this ) |
136 | { |
137 | result = scmManager.update( repository, fileSet, scmVersion, configuration.getLatestUpdateDate() ); |
138 | } |
139 | |
140 | return result; |
141 | } |
142 | |
143 | public ChangeLogScmResult changeLog( ContinuumScmConfiguration configuration ) |
144 | throws ScmException |
145 | { |
146 | ScmVersion scmVersion = getScmVersion( configuration ); |
147 | |
148 | // TODO: probably need to base this from a working directory in the main configuration |
149 | File workingDirectory = configuration.getWorkingDirectory(); |
150 | |
151 | ScmRepository repository = getScmRepository( configuration ); |
152 | |
153 | ChangeLogScmResult result; |
154 | |
155 | ScmFileSet fileSet = new ScmFileSet( workingDirectory ); |
156 | |
157 | result = scmManager.changeLog( repository, fileSet, scmVersion, scmVersion ); |
158 | |
159 | return result; |
160 | } |
161 | |
162 | /** |
163 | * Create a Maven SCM repository for obtaining the checkout from. |
164 | * |
165 | * @param configuration the configuration for the working copy and SCM |
166 | * @return the repository created |
167 | * @throws NoSuchScmProviderException |
168 | * @throws ScmRepositoryException |
169 | */ |
170 | private ScmRepository getScmRepository( ContinuumScmConfiguration configuration ) |
171 | throws ScmRepositoryException, NoSuchScmProviderException |
172 | { |
173 | ScmRepository repository = scmManager.makeScmRepository( configuration.getUrl() ); |
174 | |
175 | // TODO: tie together with the clientspec change below |
176 | // This checkout will be retained between uses, so it remains connected to the repository |
177 | repository.getProviderRepository().setPersistCheckout( true ); |
178 | |
179 | // TODO: should this be svnexe? |
180 | if ( !configuration.isUseCredentialsCache() || !"svn".equals( repository.getProvider() ) ) |
181 | { |
182 | if ( !StringUtils.isEmpty( configuration.getUsername() ) ) |
183 | { |
184 | repository.getProviderRepository().setUser( configuration.getUsername() ); |
185 | |
186 | if ( !StringUtils.isEmpty( configuration.getPassword() ) ) |
187 | { |
188 | repository.getProviderRepository().setPassword( configuration.getPassword() ); |
189 | } |
190 | else |
191 | { |
192 | repository.getProviderRepository().setPassword( "" ); |
193 | } |
194 | } |
195 | } |
196 | |
197 | if ( "perforce".equals( repository.getProvider() ) ) |
198 | { |
199 | // TODO: remove the use of system property - need a better way to pass provider specific configuration |
200 | |
201 | // Remove the clientspec name, so it will be recalculated between each command for each project |
202 | // instead of use the same for all projects |
203 | System.setProperty( "maven.scm.perforce.clientspec.name", "" ); |
204 | } |
205 | |
206 | return repository; |
207 | } |
208 | |
209 | public ScmManager getScmManager() |
210 | { |
211 | return scmManager; |
212 | } |
213 | |
214 | public void setScmManager( ScmManager scmManager ) |
215 | { |
216 | this.scmManager = scmManager; |
217 | } |
218 | |
219 | // TODO: add a nuke() method |
220 | } |