aboutsummaryrefslogtreecommitdiffstats
path: root/src/main/java/com/googlesource/gerrit/plugins/qtcodereview/QtCommandAdminChangeStatus.java
blob: f128b333a353e9b6e085cf26992a6cd58945bd25 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
//
// Copyright (C) 2019 The Qt Company
//

package com.googlesource.gerrit.plugins.qtcodereview;

import com.google.common.flogger.FluentLogger;
import com.google.gerrit.common.data.GlobalCapability;
import com.google.gerrit.extensions.annotations.RequiresCapability;
import com.google.gerrit.extensions.restapi.RestApiException;
import com.google.gerrit.reviewdb.client.Change;
import com.google.gerrit.reviewdb.client.Project;
import com.google.gerrit.reviewdb.server.ReviewDb;
import com.google.gerrit.server.query.change.InternalChangeQuery;
import com.google.gerrit.server.query.change.ChangeData;
import com.google.gerrit.server.update.BatchUpdate;
import com.google.gerrit.server.update.UpdateException;
import com.google.gerrit.server.util.time.TimeUtil;
import com.google.gerrit.sshd.SshCommand;
import com.google.gerrit.sshd.CommandMetaData;
import com.google.gwtorm.server.OrmException;

import com.google.inject.Inject;
import com.google.inject.Provider;

import java.lang.NumberFormatException;
import java.util.List;

import org.kohsuke.args4j.Option;

@RequiresCapability(GlobalCapability.ADMINISTRATE_SERVER)
@CommandMetaData(name="change-status", description="Modify change status for admins. NOTE: This only affects change attribure. No real git merge or revert will be performed.")
class QtCommandAdminChangeStatus extends SshCommand {

    @Inject
    private Provider<ReviewDb> dbProvider;

    @Inject
    Provider<InternalChangeQuery> queryProvider;

    @Inject
    private BatchUpdate.Factory updateFactory;

    @Inject
    private QtChangeUpdateOp.Factory qtUpdateFactory;

    @Option(name = "--project", aliases = {"-p"},
        required = true, usage = "project name")
    private String project;

    @Option(name = "--change-id", aliases = {"-c"},
        required = true, usage = "change id (numeric, like in web url)")
    private String changeId;

    @Option(name = "--from",
        required = true, usage = "new, staged, integrating, merged, abandoned, deferred")
    private String fromStr;

    @Option(name = "--to",
        required = true, usage = "new, staged, integrating, merged, abandoned, deferred")
    private String toStr;

    private static final FluentLogger logger = FluentLogger.forEnclosingClass();

    @Override
    protected void run() throws UnloggedFailure {
        logger.atInfo().log("qtcodereview: admin change-status start " + changeId);

        try {
            Change.Status to = toStatus(toStr);
            if (to == null) throw die("invalid to status");

            Change.Status from = toStatus(fromStr);
            if (from == null) throw die("invalid from status");

            Change.Id id = Change.Id.parse(changeId);
            if (id.get() == 0) throw die("invalid change-id");

            InternalChangeQuery query = queryProvider.get();
            List<ChangeData> list = query.byLegacyChangeId(id);
            if (list.isEmpty()) throw die("change not found");
            if (list.size() > 1) throw die("multiple changes found");
            ChangeData change = list.get(0);

            Project.NameKey projectKey = QtUtil.getProjectKey(project);
            QtChangeUpdateOp op = qtUpdateFactory.create(to, null, null, null, QtUtil.TAG_ADMINCHANGE, null);
            try (BatchUpdate u =  updateFactory.create(dbProvider.get(), projectKey, user, TimeUtil.nowTs())) {
                Change c = change.change();
                if (c.getStatus() == from) {
                    u.addOp(c.getId(), op);
                    u.execute();
                } else {
                    throw die("change status was not " + fromStr);
                }
            }
            logger.atInfo().log("qtcodereview: admin change-status done");
        } catch(NumberFormatException e) {
            throw die("change-id not numeric");
        } catch(OrmException e) {
            logger.atSevere().log("qtcodereview: change-status error %s", e.getMessage());
            throw die("Database query failed");
        } catch (UpdateException | RestApiException e) {
            logger.atSevere().log("qtcodereview: change-status error %s", e.getMessage());
            throw die("Database update failed");
        }
    }

    private Change.Status toStatus(String str) {
        switch (str) {
            case "new":
                return Change.Status.NEW;
            case "staged":
                return Change.Status.STAGED;
            case "integrating":
                return Change.Status.INTEGRATING;
            case "merged":
                return Change.Status.MERGED;
            case "abandoned":
                return Change.Status.ABANDONED;
            case "deferred":
                return Change.Status.DEFERRED;
            default:
                return null;
        }
    }

}