Package pl.project13.jgit

Source Code of pl.project13.jgit.DescribeResult

/*
* This file is part of git-commit-id-plugin by Konrad Malawski <konrad.malawski@java.pl>
*
* git-commit-id-plugin 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 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.  If not, see <http://www.gnu.org/licenses/>.
*/

package pl.project13.jgit;

import com.google.common.base.Joiner;
import com.google.common.base.Optional;
import com.google.common.base.Preconditions;
import org.eclipse.jgit.lib.AbbreviatedObjectId;
import org.eclipse.jgit.lib.ObjectId;
import org.eclipse.jgit.lib.ObjectReader;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;

import java.io.IOException;
import java.util.List;

import static com.google.common.collect.Lists.newArrayList;

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

  private Optional<String> tagName = Optional.absent();

  private Optional<ObjectId> commitId = Optional.absent();
  private Optional<AbbreviatedObjectId> abbreviatedObjectId = Optional.absent();

  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(@NotNull String tagName) {
    this(tagName, false, Optional.<String>absent());
  }

  public DescribeResult(@NotNull ObjectReader objectReader, String tagName, int commitsAwayFromTag, @Nullable ObjectId commitId) {
    this(objectReader, tagName, commitsAwayFromTag, commitId, false, Optional.<String>absent(), false);
  }

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

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

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

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

  public DescribeResult(@NotNull ObjectReader objectReader, @NotNull ObjectId commitId, boolean dirty, @NotNull Optional<String> dirtyMarker) {
    this.objectReader = objectReader;

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

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

  public DescribeResult(@NotNull String tagName, boolean dirty, @NotNull Optional<String> dirtyMarker) {
    this.tagName = Optional.of(tagName);
    this.dirty = dirty;
    this.dirtyMarker = dirtyMarker.or("");
  }

  @NotNull
  public DescribeResult withCommitIdAbbrev(int n) {
    Preconditions.checkArgument(n >= 0, String.format("The --abbrev parameter must be >= 0, but it was: [%s]", 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:
   * <pre>
   * 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.
   * </pre>
   * <p/>
   * Other outputs may look like:
   * <pre>
   * 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!
   * </pre>
   * <p/>
   * For more details (on when what output will be returned etc), see <code>man git-describe</code>.
   * 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<String> parts;

    if (abbrevZeroHidesCommitsPartOfDescribe()) {
      parts = newArrayList(tag());
    } else {
      parts = newArrayList(tag(), commitsAwayFromTag(), prefixedCommitId());
    }

    return Joiner.on("-").skipNulls().join(parts) + 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 : "";
  }

  /**
   * <p>The (possibly) "g" prefixed <strong>abbriverated</strong> object id of a commit.</p>
   * <p>
   * The "g" prefix is prepended to be compatible with git's describe output, please refer to
   * <b>man git-describe</b> to check why it's included.
   * </p>
   * <p>
   * 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.
   * </p>
   * <p>
   * Notes about the abbriverated object id:<br/>
   * Git will try to use your given abbrev lenght, but when it's to 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 pl.project13.jgit.DescribeResult#commitObjectId()}.
   * </p>
   */
  @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:
   * <ul>
   *   <li>0 (special meaning - don't show commit id at all),</li>
   *   <li>the range from 2 to 40 (inclusive) are valid</li>
   * </ul>
   *
   * @return the abbreviated commit id, possibly longer than the requested len (if it wouldn't be unique)
   */
  private static Optional<AbbreviatedObjectId> createAbbreviatedCommitId(@NotNull ObjectReader objectReader, ObjectId commitId, int requestedLenght) {
    if(requestedLenght < 2) {
      // 0 means we don't want to print commit id's at all
      return Optional.absent();
    }

    try {
      AbbreviatedObjectId abbreviatedObjectId = objectReader.abbreviate(commitId, requestedLenght);
      return Optional.of(abbreviatedObjectId);
    } catch (IOException e) {
      return Optional.absent();
    }
  }

  @Nullable
  public ObjectId commitObjectId() {
    if (commitId.isPresent()) {
      return commitId.get();
    } else {
      return null;
    }
  }

  @Nullable
  public String tag() {
    return tagName.orNull();
  }
}
TOP

Related Classes of pl.project13.jgit.DescribeResult

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.