All Downloads are FREE. Search and download functionalities are using the official Maven repository.

pl.project13.core.jgit.DescribeResult Maven / Gradle / Ivy

The newest version!
/*
 * This file is part of git-commit-id-plugin-core by Konrad 'ktoso' Malawski 
 *
 * git-commit-id-plugin-core is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * git-commit-id-plugin-core is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public License
 * along with git-commit-id-plugin-core.  If not, see .
 */

package pl.project13.core.jgit;

import java.io.IOException;
import java.util.*;

import org.eclipse.jgit.lib.AbbreviatedObjectId;
import org.eclipse.jgit.lib.ObjectId;
import org.eclipse.jgit.lib.ObjectReader;

import javax.annotation.Nonnull;
import javax.annotation.Nullable;

/**
 * Represents the result of a git describe command.
 *
 * See {@link DescribeResult#toString()} for a detailed information how this result looks like.
 */
public class DescribeResult {

  private Optional tagName = Optional.empty();

  private Optional commitId = Optional.empty();
  private Optional abbreviatedObjectId = Optional.empty();

  private int abbrev = 7;
  private int commitsAwayFromTag;

  private boolean dirty;
  private String dirtyMarker;

  private boolean forceLongFormat;

  private ObjectReader objectReader;

  public static final DescribeResult EMPTY = new DescribeResult("");

  public DescribeResult(@Nonnull String tagName) {
    this(tagName, false, Optional.empty());
  }

  public DescribeResult(@Nonnull ObjectReader objectReader, String tagName, int commitsAwayFromTag, @Nonnull ObjectId commitId) {
    this(objectReader, tagName, commitsAwayFromTag, commitId, false, Optional.empty(), false);
  }

  public DescribeResult(@Nonnull ObjectReader objectReader, @Nonnull ObjectId commitId) {
    this.objectReader = objectReader;

    this.commitId = Optional.of(commitId);
    this.abbreviatedObjectId = createAbbreviatedCommitId(objectReader, commitId, this.abbrev);
  }

  public DescribeResult(@Nonnull ObjectReader objectReader, String tagName, int commitsAwayFromTag, ObjectId commitId, boolean dirty, String dirtyMarker) {
    this(objectReader, tagName, commitsAwayFromTag, commitId, dirty, Optional.of(dirtyMarker), false);
  }

  public DescribeResult(@Nonnull ObjectReader objectReader, String tagName, int commitsAwayFromTag, ObjectId commitId, boolean dirty, Optional dirtyMarker, boolean forceLongFormat) {
    this(objectReader, commitId, dirty, dirtyMarker);
    this.tagName = Optional.of(tagName);
    this.commitsAwayFromTag = commitsAwayFromTag;
    this.forceLongFormat = forceLongFormat;
  }

  public DescribeResult(@Nonnull ObjectReader objectReader, @Nonnull ObjectId commitId, boolean dirty, @Nonnull Optional dirtyMarker) {
    this.objectReader = objectReader;

    this.commitId = Optional.of(commitId);
    this.abbreviatedObjectId = createAbbreviatedCommitId(objectReader, commitId, this.abbrev);

    this.dirty = dirty;
    this.dirtyMarker = dirtyMarker.orElse("");
  }

  public DescribeResult(@Nonnull String tagName, boolean dirty, @Nonnull Optional dirtyMarker) {
    this.tagName = Optional.of(tagName);
    this.dirty = dirty;
    this.dirtyMarker = dirtyMarker.orElse("");
  }

  @Nonnull
  public DescribeResult withCommitIdAbbrev(int n) {
    if (n < 0) {
      throw new IllegalArgumentException("The --abbrev parameter must be >= 0, but it was: [" + n + "]");
    }
    this.abbrev = n;
    this.abbreviatedObjectId = createAbbreviatedCommitId(this.objectReader, this.commitId.get(), this.abbrev);
    return this;
  }

  /**
   * The format of a describe result is defined as:
   * 
   * v1.0.4-14-g2414721-DEV
   *   ^    ^    ^       ^
   *   |    |    |       |-- if a dirtyMarker was given, it will appear here if the repository is in "dirty" state
   *   |    |    |---------- the "g" prefixed commit id. The prefix is compatible with what git-describe would return - weird, but true.
   *   |    |--------------- the number of commits away from the found tag. So "2414721" is 14 commits ahead of "v1.0.4", in this example.
   *   |-------------------- the "nearest" tag, to the mentioned commit.
   * 
* * Other outputs may look like: *
   * v1.0.4 -- if the repository is "on a tag"
   * v1.0.4-DEV -- if the repository is "on a tag", but in "dirty" state
   * 2414721 -- a plain commit id hash if not tags were defined (of determined "near" this commit).
   *            It does NOT include the "g" prefix, that is used in the "full" describe output format!
   * 
* * For more details (on when what output will be returned etc), see man git-describe. * In general, you can assume it's a "best effort" approach, to give you as much info about the repo state as possible. * * @return the String representation of this Describe command */ @Override public String toString() { List parts; if (abbrevZeroHidesCommitsPartOfDescribe()) { parts = new ArrayList<>(Collections.singletonList(tag())); } else { parts = new ArrayList<>(Arrays.asList(tag(), commitsAwayFromTag(), prefixedCommitId())); } final StringJoiner sj = new StringJoiner("-"); parts.stream().filter(Objects::nonNull).forEach(sj::add); return sj.toString() + dirtyMarker(); // like in the describe spec the entire "-dirty" is configurable (incl. "-") } private boolean abbrevZeroHidesCommitsPartOfDescribe() { return abbrev == 0; } @Nullable public String commitsAwayFromTag() { if (forceLongFormat) { return String.valueOf(commitsAwayFromTag); } return commitsAwayFromTag == 0 ? null : String.valueOf(commitsAwayFromTag); } @Nullable public String dirtyMarker() { return dirty ? dirtyMarker : ""; } /** *

The (possibly) "g" prefixed abbreviated object id of a commit.

*

* The "g" prefix is prepended to be compatible with git's describe output, please refer to * man git-describe to check why it's included. *

*

* The "g" prefix is used when a tag is defined on this result. If it's not, this method yields a plain commit id hash. * This is following git's behaviour - so any git tooling should be happy with this output. *

*

* Notes about the abbreviated object id: * Git will try to use your given abbrev length, but when it's too short to guarantee uniqueness - * a longer one will be used (which WILL guarantee uniqueness). * If you need the full commit id, it's always available via {@link DescribeResult#commitObjectId()}. *

* * @return The (possibly) "g" prefixed abbreviated object id of a commit. */ @Nullable public String prefixedCommitId() { if (abbreviatedObjectId.isPresent()) { String name = abbreviatedObjectId.get().name(); return gPrefixedCommitId(name); } else if (commitId.isPresent()) { String name = commitId.get().name(); return gPrefixedCommitId(name); } else { return null; } } private String gPrefixedCommitId(String name) { if (tagName.isPresent()) { return "g" + name; } else { return name; } } /** * JGit won't ever use 1 char as abbreviated ID, that's why only values of: *
    *
  • 0 (special meaning - don't show commit id at all),
  • *
  • the range from 2 to 40 (inclusive) are valid
  • *
* * @return the abbreviated commit id, possibly longer than the requested len (if it wouldn't be unique) */ private static Optional createAbbreviatedCommitId(@Nonnull ObjectReader objectReader, ObjectId commitId, int requestedLength) { if (requestedLength < 2) { // 0 means we don't want to print commit id's at all return Optional.empty(); } try { AbbreviatedObjectId abbreviatedObjectId = objectReader.abbreviate(commitId, requestedLength); return Optional.of(abbreviatedObjectId); } catch (IOException e) { return Optional.empty(); } } @Nullable public ObjectId commitObjectId() { return commitId.orElse(null); } @Nullable public String tag() { return tagName.orElse(null); } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy