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.client.cli;
020
021import java.io.File;
022import java.util.List;
023
024import org.apache.maven.scm.ScmBranch;
025import org.apache.maven.scm.ScmException;
026import org.apache.maven.scm.ScmFile;
027import org.apache.maven.scm.ScmFileSet;
028import org.apache.maven.scm.ScmResult;
029import org.apache.maven.scm.ScmRevision;
030import org.apache.maven.scm.ScmTag;
031import org.apache.maven.scm.ScmVersion;
032import org.apache.maven.scm.command.checkin.CheckInScmResult;
033import org.apache.maven.scm.command.checkout.CheckOutScmResult;
034import org.apache.maven.scm.command.update.UpdateScmResult;
035import org.apache.maven.scm.manager.NoSuchScmProviderException;
036import org.apache.maven.scm.manager.ScmManager;
037import org.apache.maven.scm.repository.ScmRepository;
038import org.apache.maven.scm.repository.ScmRepositoryException;
039import org.codehaus.plexus.ContainerConfiguration;
040import org.codehaus.plexus.DefaultContainerConfiguration;
041import org.codehaus.plexus.DefaultPlexusContainer;
042import org.codehaus.plexus.PlexusConstants;
043import org.codehaus.plexus.PlexusContainer;
044import org.codehaus.plexus.PlexusContainerException;
045import org.codehaus.plexus.context.Context;
046import org.codehaus.plexus.context.DefaultContext;
047
048/**
049 * @author <a href="mailto:trygvis@inamo.no">Trygve Laugst&oslash;l</a>
050 * @author <a href="mailto:evenisse@apache.org">Emmanuel Venisse</a>
051 *
052 */
053public class MavenScmCli {
054    private PlexusContainer plexus;
055
056    private ScmManager scmManager;
057
058    // ----------------------------------------------------------------------
059    // Lifecycle
060    // ----------------------------------------------------------------------
061
062    public MavenScmCli() throws Exception {
063        plexus = createPlexusContainer();
064        scmManager = plexus.lookup(ScmManager.class);
065    }
066
067    private PlexusContainer createPlexusContainer() {
068        final Context context = new DefaultContext();
069        String path = System.getProperty("basedir");
070        if (path == null) {
071            path = new File("").getAbsolutePath();
072        }
073        context.put("basedir", path);
074
075        ContainerConfiguration plexusConfiguration = new DefaultContainerConfiguration();
076        plexusConfiguration
077                .setName("maven-scm-cli")
078                .setContext(context.getContextData())
079                .setClassPathScanning(PlexusConstants.SCANNING_CACHE)
080                .setAutoWiring(true);
081        try {
082            return new DefaultPlexusContainer(plexusConfiguration);
083        } catch (PlexusContainerException e) {
084            throw new IllegalStateException("Could not create Plexus container", e);
085        }
086    }
087
088    public void stop() {
089        try {
090            plexus.dispose();
091        } catch (Exception ex) {
092            // ignore
093        }
094    }
095
096    // ----------------------------------------------------------------------
097    //
098    // ----------------------------------------------------------------------
099
100    public static void main(String[] args) {
101        MavenScmCli cli;
102
103        try {
104            cli = new MavenScmCli();
105        } catch (Exception ex) {
106            System.err.println("Error while starting Maven SCM.");
107
108            ex.printStackTrace(System.err);
109
110            return;
111        }
112
113        String scmUrl;
114
115        String command;
116
117        if (args.length < 3) {
118            System.err.println(
119                    "Usage: maven-scm-client <command> <working directory> <scm url> [<scmVersion> [<scmVersionType>]]");
120            System.err.println("scmVersion is a branch name/tag name/revision number.");
121            System.err.println(
122                    "scmVersionType can be 'branch', 'tag', 'revision'. " + "The default value is 'revision'.");
123
124            return;
125        }
126
127        command = args[0];
128
129        // SCM-641
130        File workingDirectory = new File(args[1]).getAbsoluteFile();
131
132        scmUrl = args[2];
133
134        ScmVersion scmVersion = null;
135        if (args.length > 3) {
136            String version = args[3];
137
138            if (args.length > 4) {
139                String type = args[4];
140
141                if ("tag".equals(type)) {
142                    scmVersion = new ScmTag(version);
143                } else if ("branch".equals(type)) {
144                    scmVersion = new ScmBranch(version);
145                } else if ("revision".equals(type)) {
146                    scmVersion = new ScmRevision(version);
147                } else {
148                    throw new IllegalArgumentException("'" + type + "' version type isn't known.");
149                }
150            } else {
151                scmVersion = new ScmRevision(args[3]);
152            }
153        }
154
155        cli.execute(scmUrl, command, workingDirectory, scmVersion);
156
157        cli.stop();
158    }
159
160    // ----------------------------------------------------------------------
161    //
162    // ----------------------------------------------------------------------
163
164    public void execute(String scmUrl, String command, File workingDirectory, ScmVersion version) {
165        ScmRepository repository;
166
167        try {
168            repository = scmManager.makeScmRepository(scmUrl);
169        } catch (NoSuchScmProviderException ex) {
170            System.err.println("Could not find a provider.");
171
172            return;
173        } catch (ScmRepositoryException ex) {
174            System.err.println("Error while connecting to the repository");
175
176            ex.printStackTrace(System.err);
177
178            return;
179        }
180
181        try {
182            if (command.equals("checkout")) {
183                checkOut(repository, workingDirectory, version);
184            } else if (command.equals("checkin")) {
185                checkIn(repository, workingDirectory, version);
186            } else if (command.equals("update")) {
187                update(repository, workingDirectory, version);
188            } else {
189                System.err.println("Unknown SCM command '" + command + "'.");
190            }
191        } catch (ScmException ex) {
192            System.err.println("Error while executing the SCM command.");
193
194            ex.printStackTrace(System.err);
195
196            return;
197        }
198    }
199
200    // ----------------------------------------------------------------------
201    //
202    // ----------------------------------------------------------------------
203
204    private void checkOut(ScmRepository scmRepository, File workingDirectory, ScmVersion version) throws ScmException {
205        if (workingDirectory.exists()) {
206            System.err.println("The working directory already exist: '" + workingDirectory.getAbsolutePath() + "'.");
207
208            return;
209        }
210
211        if (!workingDirectory.mkdirs()) {
212            System.err.println(
213                    "Error while making the working directory: '" + workingDirectory.getAbsolutePath() + "'.");
214
215            return;
216        }
217
218        CheckOutScmResult result = scmManager.checkOut(scmRepository, new ScmFileSet(workingDirectory), version);
219
220        if (!result.isSuccess()) {
221            showError(result);
222
223            return;
224        }
225
226        List<ScmFile> checkedOutFiles = result.getCheckedOutFiles();
227
228        System.out.println("Checked out these files: ");
229
230        for (ScmFile file : checkedOutFiles) {
231            System.out.println(" " + file.getPath());
232        }
233    }
234
235    private void checkIn(ScmRepository scmRepository, File workingDirectory, ScmVersion version) throws ScmException {
236        if (!workingDirectory.exists()) {
237            System.err.println("The working directory doesn't exist: '" + workingDirectory.getAbsolutePath() + "'.");
238
239            return;
240        }
241
242        String message = "";
243
244        CheckInScmResult result = scmManager.checkIn(scmRepository, new ScmFileSet(workingDirectory), version, message);
245
246        if (!result.isSuccess()) {
247            showError(result);
248
249            return;
250        }
251
252        List<ScmFile> checkedInFiles = result.getCheckedInFiles();
253
254        System.out.println("Checked in these files: ");
255
256        for (ScmFile file : checkedInFiles) {
257            System.out.println(" " + file.getPath());
258        }
259    }
260
261    private void update(ScmRepository scmRepository, File workingDirectory, ScmVersion version) throws ScmException {
262        if (!workingDirectory.exists()) {
263            System.err.println("The working directory doesn't exist: '" + workingDirectory.getAbsolutePath() + "'.");
264
265            return;
266        }
267
268        UpdateScmResult result = scmManager.update(scmRepository, new ScmFileSet(workingDirectory), version);
269
270        if (!result.isSuccess()) {
271            showError(result);
272
273            return;
274        }
275
276        List<ScmFile> updatedFiles = result.getUpdatedFiles();
277
278        System.out.println("Updated these files: ");
279
280        for (ScmFile file : updatedFiles) {
281            System.out.println(" " + file.getPath());
282        }
283    }
284
285    // ----------------------------------------------------------------------
286    //
287    // ----------------------------------------------------------------------
288
289    private void showError(ScmResult result) {
290        System.err.println("There was a error while executing the SCM command.");
291
292        String providerMessage = result.getProviderMessage();
293
294        if (!(providerMessage == null || providerMessage.isEmpty())) {
295            System.err.println("Error message from the provider: " + providerMessage);
296        } else {
297            System.err.println("The provider didn't give a error message.");
298        }
299
300        String output = result.getCommandOutput();
301
302        if (!(output == null || output.isEmpty())) {
303            System.err.println("Command output:");
304
305            System.err.println(output);
306        }
307    }
308}