Skip to content

Commit

Permalink
API: Add IcebergBuild info (#5237)
Browse files Browse the repository at this point in the history
  • Loading branch information
rdblue authored Jul 11, 2022
1 parent 82ef2dc commit 62739b8
Show file tree
Hide file tree
Showing 4 changed files with 199 additions and 20 deletions.
120 changes: 120 additions & 0 deletions api/src/main/java/org/apache/iceberg/IcebergBuild.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,120 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you 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.iceberg;

import java.io.IOException;
import java.io.InputStream;
import java.util.List;
import java.util.Properties;
import org.apache.iceberg.relocated.com.google.common.base.Splitter;
import org.apache.iceberg.relocated.com.google.common.collect.ImmutableList;
import org.apache.iceberg.relocated.com.google.common.io.Resources;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
* Loads iceberg-version.properties with build information.
*/
public class IcebergBuild {
private IcebergBuild() {
}

private static final Logger LOG = LoggerFactory.getLogger(IcebergBuild.class);
private static final String VERSION_PROPERTIES_FILE = "/iceberg-build.properties";
private static final String UNKNOWN_DEFAULT = "unknown";

private static volatile boolean isLoaded = false;

private static String shortId; // 10 character short git hash of the build
private static String commitId; // 40 character full git hash of the build
private static String branch;
private static List<String> tags;
private static String version;
private static String fullVersion;

/**
* Loads the version.properties file for this module.
*/
public static void loadBuildInfo() {
Properties buildProperties = new Properties();
try (InputStream is = readResource(VERSION_PROPERTIES_FILE)) {
buildProperties.load(is);
} catch (Exception e) {
LOG.warn("Failed to load version properties from {}", VERSION_PROPERTIES_FILE, e);
}

IcebergBuild.shortId = buildProperties.getProperty("git.commit.id.abbrev", UNKNOWN_DEFAULT);
IcebergBuild.commitId = buildProperties.getProperty("git.commit.id", UNKNOWN_DEFAULT);
IcebergBuild.branch = buildProperties.getProperty("git.branch", UNKNOWN_DEFAULT);
String tagList = buildProperties.getProperty("git.tags", "");
if (!tagList.isEmpty()) {
IcebergBuild.tags = ImmutableList.copyOf(Splitter.on(",").split(tagList));
} else {
IcebergBuild.tags = ImmutableList.of();
}
IcebergBuild.version = buildProperties.getProperty("git.build.version", UNKNOWN_DEFAULT);
IcebergBuild.fullVersion = String.format("Apache Iceberg %s (commit %s)", version, commitId);
}

public static String gitCommitId() {
ensureLoaded();
return commitId;
}

public static String gitCommitShortId() {
ensureLoaded();
return shortId;
}

public static String gitBranch() {
ensureLoaded();
return branch;
}

public static List<String> gitTags() {
ensureLoaded();
return tags;
}

public static String version() {
ensureLoaded();
return version;
}

public static String fullVersion() {
ensureLoaded();
return fullVersion;
}

private static void ensureLoaded() {
if (!isLoaded) {
synchronized (IcebergBuild.class) {
if (!isLoaded) {
loadBuildInfo();
isLoaded = true;
}
}
}
}

private static InputStream readResource(String resourceName) throws IOException {
return Resources.asByteSource(Resources.getResource(IcebergBuild.class, resourceName)).openStream();
}
}
47 changes: 47 additions & 0 deletions api/src/test/java/org/apache/iceberg/TestIcebergBuild.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you 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.iceberg;

import java.util.Locale;
import java.util.regex.Pattern;
import org.junit.Assert;
import org.junit.Test;

public class TestIcebergBuild {
@Test
public void testFullVersion() {
Assert.assertEquals(
"Should build full version from version and commit ID",
"Apache Iceberg " + IcebergBuild.version() + " (commit " + IcebergBuild.gitCommitId() + ")",
IcebergBuild.fullVersion());
}

@Test
public void testVersion() {
Assert.assertNotEquals("Should not use unknown version", "unknown", IcebergBuild.version());
}

@Test
public void testGitCommitId() {
Assert.assertNotEquals("Should not use unknown commit ID", "unknown", IcebergBuild.gitCommitId());
Assert.assertTrue("Should be a hexadecimal string of 20 bytes",
Pattern.compile("[0-9a-f]{40}").matcher(IcebergBuild.gitCommitId().toLowerCase(Locale.ROOT)).matches());
}
}
41 changes: 32 additions & 9 deletions build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -45,15 +45,6 @@ plugins {
try {
// apply these plugins in a try-catch block so that we can handle cases without .git directory
apply plugin: 'com.palantir.git-version'
apply plugin: 'com.gorylenko.gradle-git-properties'
// git properties file for the root project for adding to the source tarball
gitProperties {
gitPropertiesName = 'iceberg-build.properties'
gitPropertiesResourceDir = file("${rootDir}/build")
extProperty = 'gitProps'
failOnNoGitDirectory = true
}
generateGitProperties.outputs.upToDateWhen { false }
} catch (Exception e) {
project.logger.error(e.getMessage())
}
Expand All @@ -66,6 +57,28 @@ if (JavaVersion.current() == JavaVersion.VERSION_1_8) {
throw new GradleException("This build must be run with JDK 8 or 11 but was executed with JDK " + JavaVersion.current())
}

apply plugin: 'com.gorylenko.gradle-git-properties'
// git properties file for the root project for adding to the source tarball
gitProperties {
gitPropertiesName = 'iceberg-build.properties'
gitPropertiesResourceDir = file("${rootDir}/build")
extProperty = 'gitProps'
failOnNoGitDirectory = true
}
generateGitProperties.outputs.upToDateWhen { false }

if (file("${rootDir}/iceberg-build.properties").exists()) {
tasks.register('buildInfo', Exec) {
project.logger.info('Using build info from iceberg-build.properties')
commandLine 'cp', "${rootDir}/iceberg-build.properties", 'build/iceberg-build.properties'
}
} else {
tasks.register('buildInfo') {
project.logger.info('Generating iceberg-build.properties from git')
dependsOn generateGitProperties
}
}

dependencyRecommendations {
propertiesFile file: file('versions.props')
}
Expand Down Expand Up @@ -210,6 +223,16 @@ project(':iceberg-api') {
compileOnly "com.google.errorprone:error_prone_annotations"
testImplementation "org.apache.avro:avro"
}

tasks.test.dependsOn rootProject.tasks.buildInfo

sourceSets {
test {
resources {
srcDir "${rootDir}/build"
}
}
}
}

project(':iceberg-common') {
Expand Down
11 changes: 0 additions & 11 deletions tasks.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -55,14 +55,3 @@ task deploySite(type: Exec) {
commandLine('./deploy.sh')
}

if (file("${rootDir}/iceberg-build.properties").exists()) {
tasks.register('buildInfo', Exec) {
project.logger.info('Using build info from iceberg-build.properties')
commandLine 'cp', "${rootDir}/iceberg-build.properties", 'build/iceberg-build.properties'
}
} else {
tasks.register('buildInfo') {
project.logger.info('Generating iceberg-build.properties from git')
dependsOn generateGitProperties
}
}

0 comments on commit 62739b8

Please sign in to comment.