hadoop VersionInfoMojo 源码

  • 2022-10-20
  • 浏览 (130)

haddop VersionInfoMojo 代码

文件路径:/hadoop-maven-plugins/src/main/java/org/apache/hadoop/maven/plugin/versioninfo/VersionInfoMojo.java

/*
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package org.apache.hadoop.maven.plugin.versioninfo;

import java.io.Serializable;
import java.util.Locale;
import org.apache.hadoop.maven.plugin.util.Exec;
import org.apache.hadoop.maven.plugin.util.FileSetUtils;
import org.apache.maven.model.FileSet;
import org.apache.maven.plugin.AbstractMojo;
import org.apache.maven.plugin.MojoExecutionException;
import org.apache.maven.plugins.annotations.Mojo;
import org.apache.maven.plugins.annotations.Parameter;
import org.apache.maven.project.MavenProject;

import java.io.File;
import java.io.IOException;
import java.io.RandomAccessFile;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Comparator;
import java.util.Date;
import java.util.List;
import java.util.TimeZone;

/**
 * VersionInfoMojo calculates information about the current version of the
 * codebase and exports the information as properties for further use in a Maven
 * build.  The version information includes build time, SCM URI, SCM branch, SCM
 * commit, and an MD5 checksum of the contents of the files in the codebase.
 */
@Mojo(name="version-info")
public class VersionInfoMojo extends AbstractMojo {

  @Parameter(defaultValue="${project}", readonly=true)
  private MavenProject project;

  @Parameter(required=true)
  private FileSet source;

  @Parameter(defaultValue="version-info.build.time")
  private String buildTimeProperty;

  @Parameter(defaultValue="version-info.source.md5")
  private String md5Property;

  @Parameter(defaultValue="version-info.scm.uri")
  private String scmUriProperty;

  @Parameter(defaultValue="version-info.scm.branch")
  private String scmBranchProperty;

  @Parameter(defaultValue="version-info.scm.commit")
  private String scmCommitProperty;

  @Parameter(defaultValue="git")
  private String gitCommand;

  private enum SCM {NONE, GIT}

  @Override
  public void execute() throws MojoExecutionException {
    try {
      SCM scm = determineSCM();
      project.getProperties().setProperty(buildTimeProperty, getBuildTime());
      project.getProperties().setProperty(scmUriProperty, getSCMUri(scm));
      project.getProperties().setProperty(scmBranchProperty, getSCMBranch(scm));
      project.getProperties().setProperty(scmCommitProperty, getSCMCommit(scm));
      project.getProperties().setProperty(md5Property, computeMD5());
    } catch (Throwable ex) {
      throw new MojoExecutionException(ex.toString(), ex);
    }
  }

  /**
   * Returns a string representing current build time.
   * 
   * @return String representing current build time
   */
  private String getBuildTime() {
    DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm'Z'");
    dateFormat.setTimeZone(TimeZone.getTimeZone("UTC"));
    return dateFormat.format(new Date());
  }
  private List<String> scmOut;

  /**
   * Determines which SCM is in use (git or none) and captures
   * output of the SCM command for later parsing.
   * 
   * @return SCM in use for this build
   * @throws Exception if any error occurs attempting to determine SCM
   */
  private SCM determineSCM() throws Exception {
    Exec exec = new Exec(this);
    SCM scm = SCM.NONE;
    scmOut = new ArrayList<String>();
    int ret;
    ret = exec.run(Arrays.asList(gitCommand, "branch"), scmOut);
    if (ret == 0) {
      ret = exec.run(Arrays.asList(gitCommand, "remote", "-v"), scmOut);
      if (ret != 0) {
        scm = SCM.NONE;
        scmOut = null;
      } else {
        ret = exec.run(Arrays.asList(gitCommand, "log", "-n", "1"), scmOut);
        if (ret != 0) {
          scm = SCM.NONE;
          scmOut = null;
        } else {
          scm = SCM.GIT;
        }
      }
    }

    if (scmOut != null) {
      getLog().debug(scmOut.toString());
    }
    getLog().info("SCM: " + scm);
    return scm;
  }

  /**
   * Parses SCM output and returns URI of SCM.
   * 
   * @param scm SCM in use for this build
   * @return String URI of SCM
   */
  private String getSCMUri(SCM scm) {
    String uri = "Unknown";
    switch (scm) {
      case GIT:
        for (String s : scmOut) {
          if (s.startsWith("origin") && s.endsWith("(fetch)")) {
            uri = s.substring("origin".length());
            uri = uri.substring(0, uri.length() - "(fetch)".length());
            break;
          }
        }
        break;
    }
    return uri.trim();
  }

  /**
   * Parses SCM output and returns commit of SCM.
   * 
   * @param scm SCM in use for this build
   * @return String commit of SCM
   */
  private String getSCMCommit(SCM scm) {
    String commit = "Unknown";
    switch (scm) {
      case GIT:
        for (String s : scmOut) {
          if (s.startsWith("commit")) {
            commit = s.substring("commit".length());
            break;
          }
        }
        break;
    }
    return commit.trim();
  }

  /**
   * Parses SCM output and returns branch of SCM.
   * 
   * @param scm SCM in use for this build
   * @return String branch of SCM
   */
  private String getSCMBranch(SCM scm) {
    String branch = "Unknown";
    switch (scm) {
      case GIT:
        for (String s : scmOut) {
          if (s.startsWith("*")) {
            branch = s.substring("*".length());
            break;
          }
        }
        break;
    }
    return branch.trim();
  }

  /**
   * Reads and returns the full contents of the specified file.
   * 
   * @param file File to read
   * @return byte[] containing full contents of file
   * @throws IOException if there is an I/O error while reading the file
   */
  private byte[] readFile(File file) throws IOException {
    RandomAccessFile raf = new RandomAccessFile(file, "r");
    byte[] buffer = new byte[(int) raf.length()];
    raf.readFully(buffer);
    raf.close();
    return buffer;
  }

  /**
   * Given a list of files, computes and returns an MD5 checksum of the full
   * contents of all files.
   * 
   * @param files List<File> containing every file to input into the MD5 checksum
   * @return byte[] calculated MD5 checksum
   * @throws IOException if there is an I/O error while reading a file
   * @throws NoSuchAlgorithmException if the MD5 algorithm is not supported
   */
  private byte[] computeMD5(List<File> files) throws IOException, NoSuchAlgorithmException {
    MessageDigest md5 = MessageDigest.getInstance("MD5");
    for (File file : files) {
      getLog().debug("Computing MD5 for: " + file);
      md5.update(readFile(file));
    }
    return md5.digest();
  }

  /**
   * Converts bytes to a hexadecimal string representation and returns it.
   * 
   * @param array byte[] to convert
   * @return String containing hexadecimal representation of bytes
   */
  private String byteArrayToString(byte[] array) {
    StringBuilder sb = new StringBuilder();
    for (byte b : array) {
      sb.append(Integer.toHexString(0xff & b));
    }
    return sb.toString();
  }

  static class MD5Comparator implements Comparator<File>, Serializable {
    private static final long serialVersionUID = 1L;

    @Override
    public int compare(File lhs, File rhs) {
      return normalizePath(lhs).compareTo(normalizePath(rhs));
    }

    private String normalizePath(File file) {
      return file.getPath().toUpperCase(Locale.ENGLISH)
          .replaceAll("\\\\", "/");
    }
  }

  /**
   * Computes and returns an MD5 checksum of the contents of all files in the
   * input Maven FileSet.
   * 
   * @return String containing hexadecimal representation of MD5 checksum
   * @throws Exception if there is any error while computing the MD5 checksum
   */
  private String computeMD5() throws Exception {
    List<File> files = FileSetUtils.convertFileSetToFiles(source);
    // File order of MD5 calculation is significant.  Sorting is done on
    // unix-format names, case-folded, in order to get a platform-independent
    // sort and calculate the same MD5 on all platforms.
    Collections.sort(files, new MD5Comparator());
    byte[] md5 = computeMD5(files);
    String md5str = byteArrayToString(md5);
    getLog().info("Computed MD5: " + md5str);
    return md5str;
  }
}

相关信息

hadoop 源码目录

相关文章

hadoop BufferPool 源码

hadoop ByteBufferInputStream 源码

hadoop ByteBufferOutputStream 源码

hadoop ByteBufferWrapper 源码

hadoop Constants 源码

hadoop CosN 源码

hadoop CosNConfigKeys 源码

hadoop CosNCopyFileContext 源码

hadoop CosNCopyFileTask 源码

hadoop CosNFileReadTask 源码

0  赞