LCOV - code coverage report
Current view: top level - server/restapi/change - GetArchive.java (source / functions) Hit Total Coverage
Test: _coverage_report.dat Lines: 35 38 92.1 %
Date: 2022-11-19 15:00:39 Functions: 7 7 100.0 %

          Line data    Source code
       1             : // Copyright (C) 2014 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.restapi.change;
      16             : 
      17             : import static com.google.gerrit.git.ObjectIds.abbreviateName;
      18             : 
      19             : import com.google.common.base.Strings;
      20             : import com.google.gerrit.common.Nullable;
      21             : import com.google.gerrit.extensions.restapi.BadRequestException;
      22             : import com.google.gerrit.extensions.restapi.BinaryResult;
      23             : import com.google.gerrit.extensions.restapi.MethodNotAllowedException;
      24             : import com.google.gerrit.extensions.restapi.Response;
      25             : import com.google.gerrit.extensions.restapi.RestReadView;
      26             : import com.google.gerrit.server.change.ArchiveFormatInternal;
      27             : import com.google.gerrit.server.change.RevisionResource;
      28             : import com.google.gerrit.server.git.GitRepositoryManager;
      29             : import com.google.inject.Inject;
      30             : import java.io.IOException;
      31             : import java.io.OutputStream;
      32             : import org.eclipse.jgit.api.ArchiveCommand;
      33             : import org.eclipse.jgit.api.errors.GitAPIException;
      34             : import org.eclipse.jgit.lib.Repository;
      35             : import org.eclipse.jgit.revwalk.RevCommit;
      36             : import org.eclipse.jgit.revwalk.RevWalk;
      37             : import org.kohsuke.args4j.Option;
      38             : 
      39             : public class GetArchive implements RestReadView<RevisionResource> {
      40             :   private final GitRepositoryManager repoManager;
      41             :   private final AllowedFormats allowedFormats;
      42             :   @Nullable private String format;
      43             : 
      44             :   @Option(name = "--format")
      45             :   public void setFormat(String format) {
      46           1 :     this.format = format;
      47           1 :   }
      48             : 
      49             :   @Inject
      50          57 :   GetArchive(GitRepositoryManager repoManager, AllowedFormats allowedFormats) {
      51          57 :     this.repoManager = repoManager;
      52          57 :     this.allowedFormats = allowedFormats;
      53          57 :   }
      54             : 
      55             :   @Override
      56             :   public Response<BinaryResult> apply(RevisionResource rsrc)
      57             :       throws BadRequestException, IOException, MethodNotAllowedException {
      58           2 :     if (Strings.isNullOrEmpty(format)) {
      59           2 :       throw new BadRequestException("format is not specified");
      60             :     }
      61           1 :     ArchiveFormatInternal f = allowedFormats.extensions.get("." + format);
      62           1 :     if (f == null) {
      63           1 :       throw new BadRequestException("unknown archive format");
      64             :     }
      65           1 :     if (f == ArchiveFormatInternal.ZIP) {
      66           1 :       throw new MethodNotAllowedException("zip format is disabled");
      67             :     }
      68           1 :     boolean close = true;
      69           1 :     Repository repo = repoManager.openRepository(rsrc.getProject());
      70             :     try {
      71             :       RevCommit commit;
      72             :       String name;
      73           1 :       try (RevWalk rw = new RevWalk(repo)) {
      74           1 :         commit = rw.parseCommit(rsrc.getPatchSet().commitId());
      75           1 :         name = name(f, rw, commit);
      76             :       }
      77             : 
      78           1 :       BinaryResult bin =
      79           1 :           new BinaryResult() {
      80             :             @Override
      81             :             public void writeTo(OutputStream out) throws IOException {
      82             :               try {
      83           1 :                 new ArchiveCommand(repo)
      84           1 :                     .setFormat(f.name())
      85           1 :                     .setTree(commit.getTree())
      86           1 :                     .setOutputStream(out)
      87           1 :                     .call();
      88           0 :               } catch (GitAPIException e) {
      89           0 :                 throw new IOException(e);
      90           1 :               }
      91           1 :             }
      92             : 
      93             :             @Override
      94             :             public void close() throws IOException {
      95           1 :               repo.close();
      96           1 :             }
      97             :           };
      98             : 
      99           1 :       bin.disableGzip().setContentType(f.getMimeType()).setAttachmentName(name);
     100             : 
     101           1 :       close = false;
     102           1 :       return Response.ok(bin);
     103             :     } finally {
     104           1 :       if (close) {
     105           0 :         repo.close();
     106             :       }
     107             :     }
     108             :   }
     109             : 
     110             :   private static String name(ArchiveFormatInternal format, RevWalk rw, RevCommit commit)
     111             :       throws IOException {
     112           1 :     return String.format(
     113           1 :         "%s%s", abbreviateName(commit, rw.getObjectReader()), format.getDefaultSuffix());
     114             :   }
     115             : }

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