View Javadoc

1   /*
2   Karma core - Core of the Karma application
3   Copyright (C) 2004  Toolforge <www.toolforge.nl>
4   
5   This library is free software; you can redistribute it and/or
6   modify it under the terms of the GNU Lesser General Public
7   License as published by the Free Software Foundation; either
8   version 2.1 of the License, or (at your option) any later version.
9   
10  This library is distributed in the hope that it will be useful,
11  but WITHOUT ANY WARRANTY; without even the implied warranty of
12  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13  Lesser General Public License for more details.
14  
15  You should have received a copy of the GNU Lesser General Public
16  License along with this library; if not, write to the Free Software
17  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
18  */
19  package nl.toolforge.karma.core.cmd.impl;
20  
21  import nl.toolforge.karma.core.Version;
22  import nl.toolforge.karma.core.cmd.CommandDescriptor;
23  import nl.toolforge.karma.core.cmd.CommandException;
24  import nl.toolforge.karma.core.cmd.CommandResponse;
25  import nl.toolforge.karma.core.cmd.DefaultCommand;
26  import nl.toolforge.karma.core.cmd.event.ErrorEvent;
27  import nl.toolforge.karma.core.cmd.event.MessageEvent;
28  import nl.toolforge.karma.core.cmd.event.SimpleMessage;
29  import nl.toolforge.karma.core.manifest.DevelopmentManifest;
30  import nl.toolforge.karma.core.manifest.Manifest;
31  import nl.toolforge.karma.core.manifest.ManifestException;
32  import nl.toolforge.karma.core.module.Module;
33  import nl.toolforge.karma.core.vc.AuthenticationException;
34  import nl.toolforge.karma.core.vc.ModuleStatus;
35  import nl.toolforge.karma.core.vc.Runner;
36  import nl.toolforge.karma.core.vc.RunnerFactory;
37  import nl.toolforge.karma.core.vc.VersionControlException;
38  import nl.toolforge.karma.core.vc.cvsimpl.AdminHandler;
39  import nl.toolforge.karma.core.vc.cvsimpl.CVSModuleStatus;
40  import nl.toolforge.karma.core.vc.cvsimpl.CVSRunner;
41  
42  /***
43   * Implementation of the 'codeline freeze' concept. Karma increases a modules' version (using whichever pattern is
44   * defined for it), thus allowing for a freeze. Development can commence immediately on the module. In that sense, it
45   * is not a freeze, just a tiny hick-up in the development process, as modules are generally small in nature.
46   *
47   * @author D.A. Smedes
48   * @author W.H. Schraal
49   * @version $Id: PromoteCommand.java,v 1.40 2004/11/10 23:53:08 asmedes Exp $
50   */
51  public class PromoteCommand extends DefaultCommand {
52  
53    private Version newVersion = null;
54    protected CommandResponse commandResponse = new CommandResponse();
55  
56    public PromoteCommand(CommandDescriptor descriptor) {
57      super(descriptor);
58    }
59  
60    /***
61     * Promotes a module to the next version number in the branch it is active in within the active manifest.
62     * @throws CommandException if execution fails.
63     */
64    public void execute() throws CommandException {
65  
66      // todo move to aspect; this type of checking can be done by one aspect.
67      //
68      if (!getContext().isManifestLoaded()) {
69        throw new CommandException(ManifestException.NO_ACTIVE_MANIFEST);
70      }
71  
72      try {
73  
74        String moduleName = getCommandLine().getOptionValue("m");
75        String comment = getCommandLine().getOptionValue("c");
76  
77        Manifest manifest = getContext().getCurrentManifest();
78        Module module = manifest.getModule(moduleName);
79  
80        if (!manifest.getState(module).equals(Module.WORKING)) {
81          throw new CommandException(CommandException.PROMOTE_ONLY_ALLOWED_ON_WORKING_MODULE, new Object[]{moduleName});
82        }
83  
84        // Detect new files.
85        //
86        AdminHandler handler = new AdminHandler(module);
87        handler.administrate();
88  
89        boolean force = getCommandLine().hasOption("f");
90        boolean proceed = true;
91  
92        if (handler.hasNewStuff()) {
93          if (force) {
94            commandResponse.addEvent(new MessageEvent(this, new SimpleMessage("WARNING : Module " + moduleName + " has new, but uncommitted files.")));
95          } else {
96            commandResponse.addEvent(new ErrorEvent(this, CommandException.UNCOMMITTED_NEW_FILES, new Object[]{moduleName}));
97            proceed = false;
98          }
99        }
100       if (handler.hasChangedStuff()) {
101         if (force) {
102           commandResponse.addEvent(new MessageEvent(this, new SimpleMessage("WARNING : Module " + moduleName + " has changed, but uncommitted files.")));
103         } else {
104           commandResponse.addEvent(new ErrorEvent(this, CommandException.UNCOMMITTED_CHANGED_FILES, new Object[]{moduleName}));
105           proceed = false;
106         }
107       }
108       if (handler.hasRemovedStuff()) {
109         if (force) {
110           commandResponse.addEvent(new MessageEvent(this, new SimpleMessage("WARNING : Module " + moduleName + " has removed, but uncommitted files.")));
111         } else {
112           commandResponse.addEvent(new ErrorEvent(this, CommandException.UNCOMMITTED_REMOVED_FILES, new Object[]{moduleName}));
113           proceed = false;
114         }
115       }
116 
117       if (proceed) {
118         Runner runner = RunnerFactory.getRunner(module.getLocation());
119 
120         ModuleStatus status = new CVSModuleStatus(module, ((CVSRunner) runner).log(module));
121         Version nextVersion = null;
122 
123         if (getCommandLine().hasOption("v")) {
124           if (! (manifest instanceof DevelopmentManifest)) {
125             throw new CommandException(CommandException.PROMOTE_WITH_INCREASE_MAJOR_VERSION_NOT_ALLOWED_ON_RELEASE_MANIFEST);
126           }
127 
128           nextVersion = status.getNextMajorVersion();
129         } else {
130           nextVersion = status.getNextVersion();
131         }
132 
133         newVersion = nextVersion;
134 
135         runner.promote(module, comment, newVersion);
136 
137         commandResponse.addEvent(
138             new MessageEvent(this,
139                 new SimpleMessage(
140                     getFrontendMessages().getString("message.MODULE_PROMOTED"),
141                     new Object[]{getCommandLine().getOptionValue("m"), getNewVersion()}
142                 )));
143 
144       } else {
145         commandResponse.addEvent(
146             new MessageEvent(this,
147                 new SimpleMessage(
148                     getFrontendMessages().getString("message.PROMOTE_MODULE_FAILED"),
149                     new Object[]{module.getName(), moduleName}
150                 )));
151       }
152 
153     } catch (ManifestException e) {
154       throw new CommandException(e.getErrorCode(), e.getMessageArguments());
155     } catch (VersionControlException e) {
156       throw new CommandException(e.getErrorCode(), e.getMessageArguments());
157     } catch (AuthenticationException e) {
158       throw new CommandException(e.getErrorCode(), e.getMessageArguments());
159     }
160   }
161 
162   /***
163    * Gets the commands' response object.
164    *
165    * @return The commands' response object.
166    */
167   public CommandResponse getCommandResponse() {
168     return commandResponse;
169   }
170 
171   /***
172    * Returns the new version number for the module, or <code>null</code> when no version number could be set.
173    *
174    * @return The new version number for the module, or <code>null</code> when no version number could be set.
175    */
176   protected final Version getNewVersion() {
177     return newVersion;
178   }
179 }
180