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