Line data Source code
1 : // Copyright (C) 2020 The Android Open Source Project 2 : // 3 : // Licensed under the Apache License, Version 2.0 (the "License"); 4 : // you may not use this file except in compliance with the License. 5 : // You may obtain a copy of the License at 6 : // 7 : // http://www.apache.org/licenses/LICENSE-2.0 8 : // 9 : // Unless required by applicable law or agreed to in writing, software 10 : // distributed under the License is distributed on an "AS IS" BASIS, 11 : // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 : // See the License for the specific language governing permissions and 13 : // limitations under the License. 14 : 15 : package com.google.gerrit.sshd.commands; 16 : 17 : import com.google.gerrit.entities.Change; 18 : import com.google.gerrit.exceptions.StorageException; 19 : import com.google.gerrit.extensions.restapi.BadRequestException; 20 : import com.google.gerrit.server.ChangeUtil; 21 : import com.google.gerrit.server.change.ChangeResource; 22 : import com.google.gerrit.server.change.SetTopicOp; 23 : import com.google.gerrit.server.permissions.PermissionBackendException; 24 : import com.google.gerrit.server.update.BatchUpdate; 25 : import com.google.gerrit.server.util.time.TimeUtil; 26 : import com.google.gerrit.sshd.ChangeArgumentParser; 27 : import com.google.gerrit.sshd.CommandMetaData; 28 : import com.google.gerrit.sshd.SshCommand; 29 : import com.google.inject.Inject; 30 : import java.util.LinkedHashMap; 31 : import java.util.Map; 32 : import org.kohsuke.args4j.Argument; 33 : import org.kohsuke.args4j.Option; 34 : 35 : @CommandMetaData(name = "set-topic", description = "Set the topic for one or more changes") 36 : public class SetTopicCommand extends SshCommand { 37 : private final BatchUpdate.Factory updateFactory; 38 : private final ChangeArgumentParser changeArgumentParser; 39 : private final SetTopicOp.Factory topicOpFactory; 40 : 41 1 : private Map<Change.Id, ChangeResource> changes = new LinkedHashMap<>(); 42 : 43 : @Argument( 44 : index = 0, 45 : required = true, 46 : multiValued = true, 47 : metaVar = "CHANGE", 48 : usage = "changes to index") 49 : void addChange(String token) { 50 : try { 51 0 : changeArgumentParser.addChange(token, changes, null, true); 52 0 : } catch (UnloggedFailure | StorageException | PermissionBackendException e) { 53 0 : writeError("warning", e.getMessage()); 54 0 : } 55 0 : } 56 : 57 : @Option( 58 : name = "--topic", 59 : aliases = "-t", 60 : usage = "applies a topic to the given changes", 61 : metaVar = "TOPIC") 62 : private String topic; 63 : 64 : @Inject 65 : SetTopicCommand( 66 : BatchUpdate.Factory updateFactory, 67 : ChangeArgumentParser changeArgumentParser, 68 1 : SetTopicOp.Factory topicOpFactory) { 69 1 : this.updateFactory = updateFactory; 70 1 : this.changeArgumentParser = changeArgumentParser; 71 1 : this.topicOpFactory = topicOpFactory; 72 1 : } 73 : 74 : @Override 75 : public void run() throws Exception { 76 0 : if (topic != null) { 77 0 : topic = topic.trim(); 78 : } 79 : 80 0 : if (topic != null && topic.length() > ChangeUtil.TOPIC_MAX_LENGTH) { 81 0 : throw new BadRequestException( 82 0 : String.format("topic length exceeds the limit (%s)", ChangeUtil.TOPIC_MAX_LENGTH)); 83 : } 84 : 85 0 : for (ChangeResource r : changes.values()) { 86 0 : SetTopicOp op = topicOpFactory.create(topic); 87 0 : try (BatchUpdate u = updateFactory.create(r.getChange().getProject(), user, TimeUtil.now())) { 88 0 : u.addOp(r.getId(), op); 89 0 : u.execute(); 90 : } 91 0 : } 92 0 : } 93 : }