LCOV - code coverage report
Current view: top level - server/submit - SubmitDryRun.java (source / functions) Hit Total Coverage
Test: _coverage_report.dat Lines: 43 47 91.5 %
Date: 2022-11-19 15:00:39 Functions: 8 8 100.0 %

          Line data    Source code
       1             : // Copyright (C) 2015 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.server.submit;
      16             : 
      17             : import static com.google.gerrit.server.project.ProjectCache.noSuchProject;
      18             : import static java.util.stream.Collectors.toSet;
      19             : 
      20             : import com.google.common.collect.ImmutableSet;
      21             : import com.google.common.collect.Streams;
      22             : import com.google.common.flogger.FluentLogger;
      23             : import com.google.gerrit.common.Nullable;
      24             : import com.google.gerrit.entities.BranchNameKey;
      25             : import com.google.gerrit.exceptions.StorageException;
      26             : import com.google.gerrit.extensions.client.SubmitType;
      27             : import com.google.gerrit.server.CurrentUser;
      28             : import com.google.gerrit.server.git.CodeReviewCommit;
      29             : import com.google.gerrit.server.git.CodeReviewCommit.CodeReviewRevWalk;
      30             : import com.google.gerrit.server.git.MergeUtil;
      31             : import com.google.gerrit.server.git.MergeUtilFactory;
      32             : import com.google.gerrit.server.project.NoSuchProjectException;
      33             : import com.google.gerrit.server.project.ProjectCache;
      34             : import com.google.gerrit.server.project.ProjectState;
      35             : import com.google.gerrit.server.query.change.InternalChangeQuery;
      36             : import com.google.inject.Inject;
      37             : import com.google.inject.Provider;
      38             : import java.io.IOException;
      39             : import java.util.Collection;
      40             : import java.util.HashSet;
      41             : import java.util.Objects;
      42             : import java.util.Set;
      43             : import org.eclipse.jgit.lib.Constants;
      44             : import org.eclipse.jgit.lib.ObjectId;
      45             : import org.eclipse.jgit.lib.Ref;
      46             : import org.eclipse.jgit.lib.Repository;
      47             : import org.eclipse.jgit.revwalk.RevCommit;
      48             : import org.eclipse.jgit.revwalk.RevFlag;
      49             : import org.eclipse.jgit.revwalk.RevObject;
      50             : import org.eclipse.jgit.revwalk.RevTag;
      51             : import org.eclipse.jgit.revwalk.RevWalk;
      52             : 
      53             : /** Dry run of a submit strategy. */
      54             : public class SubmitDryRun {
      55         150 :   private static final FluentLogger logger = FluentLogger.forEnclosingClass();
      56             : 
      57             :   static class Arguments {
      58             :     final Repository repo;
      59             :     final CodeReviewRevWalk rw;
      60             :     final MergeUtil mergeUtil;
      61             :     final MergeSorter mergeSorter;
      62             : 
      63          21 :     Arguments(Repository repo, CodeReviewRevWalk rw, MergeUtil mergeUtil, MergeSorter mergeSorter) {
      64          21 :       this.repo = repo;
      65          21 :       this.rw = rw;
      66          21 :       this.mergeUtil = mergeUtil;
      67          21 :       this.mergeSorter = mergeSorter;
      68          21 :     }
      69             :   }
      70             : 
      71             :   public static Set<ObjectId> getAlreadyAccepted(Repository repo) throws IOException {
      72          21 :     return Streams.concat(
      73          21 :             repo.getRefDatabase().getRefsByPrefix(Constants.R_HEADS).stream(),
      74          21 :             repo.getRefDatabase().getRefsByPrefix(Constants.R_TAGS).stream())
      75          21 :         .map(Ref::getObjectId)
      76          21 :         .filter(Objects::nonNull)
      77          21 :         .collect(toSet());
      78             :   }
      79             : 
      80             :   public static Set<RevCommit> getAlreadyAccepted(Repository repo, RevWalk rw) throws IOException {
      81          21 :     Set<RevCommit> accepted = new HashSet<>();
      82          21 :     addCommits(getAlreadyAccepted(repo), rw, accepted);
      83          21 :     return accepted;
      84             :   }
      85             : 
      86             :   public static void addCommits(Iterable<ObjectId> ids, RevWalk rw, Collection<RevCommit> out)
      87             :       throws IOException {
      88          21 :     for (ObjectId id : ids) {
      89          21 :       RevObject obj = rw.parseAny(id);
      90          21 :       if (obj instanceof RevTag) {
      91           0 :         obj = rw.peel(obj);
      92             :       }
      93          21 :       if (obj instanceof RevCommit) {
      94          21 :         out.add((RevCommit) obj);
      95             :       }
      96          21 :     }
      97          21 :   }
      98             : 
      99             :   private final ProjectCache projectCache;
     100             :   private final MergeUtilFactory mergeUtilFactory;
     101             :   private final Provider<InternalChangeQuery> queryProvider;
     102             : 
     103             :   @Inject
     104             :   SubmitDryRun(
     105             :       ProjectCache projectCache,
     106             :       MergeUtilFactory mergeUtilFactory,
     107         150 :       Provider<InternalChangeQuery> queryProvider) {
     108         150 :     this.projectCache = projectCache;
     109         150 :     this.mergeUtilFactory = mergeUtilFactory;
     110         150 :     this.queryProvider = queryProvider;
     111         150 :   }
     112             : 
     113             :   public boolean run(
     114             :       @Nullable CurrentUser caller,
     115             :       SubmitType submitType,
     116             :       Repository repo,
     117             :       CodeReviewRevWalk rw,
     118             :       BranchNameKey destBranch,
     119             :       ObjectId tip,
     120             :       ObjectId toMerge,
     121             :       Set<RevCommit> alreadyAccepted)
     122             :       throws NoSuchProjectException, IOException {
     123          21 :     CodeReviewCommit tipCommit = rw.parseCommit(tip);
     124          21 :     CodeReviewCommit toMergeCommit = rw.parseCommit(toMerge);
     125          21 :     RevFlag canMerge = rw.newFlag("CAN_MERGE");
     126          21 :     toMergeCommit.add(canMerge);
     127          21 :     Arguments args =
     128             :         new Arguments(
     129             :             repo,
     130             :             rw,
     131          21 :             mergeUtilFactory.create(getProject(destBranch)),
     132             :             new MergeSorter(
     133             :                 caller,
     134             :                 rw,
     135             :                 alreadyAccepted,
     136             :                 canMerge,
     137             :                 queryProvider,
     138          21 :                 ImmutableSet.of(toMergeCommit)));
     139             : 
     140          21 :     switch (submitType) {
     141             :       case CHERRY_PICK:
     142           3 :         return CherryPick.dryRun(args, tipCommit, toMergeCommit);
     143             :       case FAST_FORWARD_ONLY:
     144           2 :         return FastForwardOnly.dryRun(args, tipCommit, toMergeCommit);
     145             :       case MERGE_ALWAYS:
     146           2 :         return MergeAlways.dryRun(args, tipCommit, toMergeCommit);
     147             :       case MERGE_IF_NECESSARY:
     148          21 :         return MergeIfNecessary.dryRun(args, tipCommit, toMergeCommit);
     149             :       case REBASE_IF_NECESSARY:
     150           2 :         return RebaseIfNecessary.dryRun(args, repo, tipCommit, toMergeCommit);
     151             :       case REBASE_ALWAYS:
     152           2 :         return RebaseAlways.dryRun(args, repo, tipCommit, toMergeCommit);
     153             :       case INHERIT:
     154             :       default:
     155           0 :         String errorMsg = "No submit strategy for: " + submitType;
     156           0 :         logger.atSevere().log("%s", errorMsg);
     157           0 :         throw new StorageException(errorMsg);
     158             :     }
     159             :   }
     160             : 
     161             :   private ProjectState getProject(BranchNameKey branch) throws NoSuchProjectException {
     162          21 :     return projectCache.get(branch.project()).orElseThrow(noSuchProject(branch.project()));
     163             :   }
     164             : }

Generated by: LCOV version 1.16+git.20220603.dfeb750