1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
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
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
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