mirror of https://github.com/apache/jclouds.git
[issue 802] Adding support for programmatically accessible version information
This commit is contained in:
parent
bbc821a776
commit
62061d8235
15
core/pom.xml
15
core/pom.xml
|
@ -114,6 +114,21 @@
|
|||
</dependencies>
|
||||
|
||||
<build>
|
||||
<resources>
|
||||
<resource>
|
||||
<directory>${project.basedir}/src/main/resources</directory>
|
||||
<excludes>
|
||||
<exclude>META-INF/jclouds-version.properties</exclude>
|
||||
</excludes>
|
||||
</resource>
|
||||
<resource>
|
||||
<filtering>true</filtering>
|
||||
<directory>${project.basedir}/src/main/resources</directory>
|
||||
<includes>
|
||||
<include>META-INF/jclouds-version.properties</include>
|
||||
</includes>
|
||||
</resource>
|
||||
</resources>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<artifactId>maven-jar-plugin</artifactId>
|
||||
|
|
|
@ -0,0 +1,106 @@
|
|||
/**
|
||||
* Licensed to jclouds, Inc. (jclouds) under one or more
|
||||
* contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. jclouds 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.jclouds;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkArgument;
|
||||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
import static java.lang.String.format;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Properties;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
import org.jclouds.javax.annotation.Nullable;
|
||||
|
||||
import com.google.common.annotations.VisibleForTesting;
|
||||
|
||||
/**
|
||||
* @author Andrew Phillips
|
||||
*/
|
||||
public class JcloudsVersion {
|
||||
@VisibleForTesting
|
||||
static final String VERSION_RESOURCE_FILE = "META-INF/jclouds-version.properties";
|
||||
private static final String VERSION_PROPERTY_NAME = "jclouds.version";
|
||||
|
||||
// TODO: stop supporting x.y.z-rc-n after the 1.3.0 release
|
||||
// x.y.z or x.y.z-rc.n or x.y.z-rc-n, optionally with -SNAPSHOT suffix - see http://semver.org
|
||||
private static final Pattern SEMANTIC_VERSION_PATTERN =
|
||||
Pattern.compile("(\\d+)\\.(\\d+)\\.(\\d+)(?:-rc[-\\.](\\d+))?(?:-SNAPSHOT)?");
|
||||
|
||||
private static final JcloudsVersion INSTANCE = new JcloudsVersion();
|
||||
|
||||
public final int majorVersion;
|
||||
public final int minorVersion;
|
||||
public final int patchVersion;
|
||||
public final boolean releaseCandidate;
|
||||
private final String version;
|
||||
|
||||
/**
|
||||
* Non-null iff {@link #releaseCandidate} is {@code true}
|
||||
*/
|
||||
public final @Nullable Integer releaseCandidateVersion;
|
||||
public final boolean snapshot;
|
||||
|
||||
@VisibleForTesting
|
||||
JcloudsVersion() {
|
||||
this(readVersionPropertyFromClasspath());
|
||||
}
|
||||
|
||||
private static String readVersionPropertyFromClasspath() {
|
||||
Properties versionProperties = new Properties();
|
||||
try {
|
||||
versionProperties.load(checkNotNull(Thread.currentThread().getContextClassLoader().getResourceAsStream(VERSION_RESOURCE_FILE), VERSION_RESOURCE_FILE));
|
||||
} catch (IOException exception) {
|
||||
throw new IllegalStateException(format("Unable to load version resource file '%s'", VERSION_RESOURCE_FILE), exception);
|
||||
}
|
||||
return checkNotNull(versionProperties.getProperty(VERSION_PROPERTY_NAME), VERSION_PROPERTY_NAME);
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
JcloudsVersion(String version) {
|
||||
Matcher versionMatcher = SEMANTIC_VERSION_PATTERN.matcher(version);
|
||||
checkArgument(versionMatcher.matches(), "Version '%s' did not match expected pattern '%s'",
|
||||
version, SEMANTIC_VERSION_PATTERN);
|
||||
this.version = version;
|
||||
// a match will produce three or four matching groups (release candidate version optional)
|
||||
majorVersion = Integer.valueOf(versionMatcher.group(1));
|
||||
minorVersion = Integer.valueOf(versionMatcher.group(2));
|
||||
patchVersion = Integer.valueOf(versionMatcher.group(3));
|
||||
String releaseCandidateVersionIfPresent = versionMatcher.group(4);
|
||||
if (releaseCandidateVersionIfPresent != null) {
|
||||
releaseCandidate = true;
|
||||
releaseCandidateVersion = Integer.valueOf(releaseCandidateVersionIfPresent);
|
||||
} else {
|
||||
releaseCandidate = false;
|
||||
releaseCandidateVersion = null;
|
||||
}
|
||||
// endsWith("T") would be cheaper but we only do this once...
|
||||
snapshot = version.endsWith("-SNAPSHOT");
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return version;
|
||||
}
|
||||
|
||||
public static JcloudsVersion get() {
|
||||
return INSTANCE;
|
||||
}
|
||||
}
|
|
@ -0,0 +1 @@
|
|||
jclouds.version=${project.version}
|
|
@ -0,0 +1,133 @@
|
|||
/**
|
||||
* Licensed to jclouds, Inc. (jclouds) under one or more
|
||||
* contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. jclouds 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.jclouds;
|
||||
|
||||
import static org.jclouds.JcloudsVersion.VERSION_RESOURCE_FILE;
|
||||
import static org.testng.Assert.*;
|
||||
|
||||
import java.io.InputStream;
|
||||
import java.util.List;
|
||||
|
||||
import org.testng.annotations.Test;
|
||||
|
||||
import com.google.common.collect.ImmutableList;
|
||||
import com.google.common.collect.Iterables;
|
||||
|
||||
/**
|
||||
* @author Andrew Phillips
|
||||
*/
|
||||
@Test(singleThreaded = true)
|
||||
public class JcloudsVersionTest {
|
||||
|
||||
@Test
|
||||
public void testFailsIfResourceFileMissing() {
|
||||
ClassLoader original = Thread.currentThread().getContextClassLoader();
|
||||
Thread.currentThread().setContextClassLoader(
|
||||
new ResourceHidingClassLoader(original, VERSION_RESOURCE_FILE));
|
||||
try {
|
||||
new JcloudsVersion();
|
||||
fail("Expected NullPointerException");
|
||||
} catch (NullPointerException expected) {
|
||||
} finally {
|
||||
Thread.currentThread().setContextClassLoader(original);
|
||||
}
|
||||
}
|
||||
|
||||
@Test(expectedExceptions = { IllegalArgumentException.class })
|
||||
public void testFailsIfInvalidVersion() {
|
||||
new JcloudsVersion("${project.version}");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testExtractsMajorMinorPatchVersions() {
|
||||
JcloudsVersion version = new JcloudsVersion("1.2.3");
|
||||
assertEquals(1, version.majorVersion);
|
||||
assertEquals(2, version.minorVersion);
|
||||
assertEquals(3, version.patchVersion);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSupportsNonSnapshot() {
|
||||
JcloudsVersion version = new JcloudsVersion("1.2.3");
|
||||
assertFalse(version.snapshot, "Expected non-snapshot");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testRecognisesSnapshot() {
|
||||
JcloudsVersion version = new JcloudsVersion("1.2.3-SNAPSHOT");
|
||||
assertTrue(version.snapshot, "Expected snapshot");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSupportsNonReleaseCandidate() {
|
||||
JcloudsVersion version = new JcloudsVersion("1.2.3");
|
||||
assertFalse(version.releaseCandidate, "Expected non-release candidate");
|
||||
assertNull(version.releaseCandidateVersion);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testRecognisesReleaseCandidate() {
|
||||
JcloudsVersion version = new JcloudsVersion("1.2.3-rc.4");
|
||||
assertTrue(version.releaseCandidate, "Expected release candidate");
|
||||
}
|
||||
|
||||
// TODO: remove once x.y.z-rc-n support is dropped after 1.3.0
|
||||
@Test
|
||||
public void testRecognisesNonSemverReleaseCandidate() {
|
||||
JcloudsVersion version = new JcloudsVersion("1.2.3-rc-4");
|
||||
assertTrue(version.releaseCandidate, "Expected release candidate");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testExtractsReleaseCandidateVersion() {
|
||||
JcloudsVersion version = new JcloudsVersion("1.2.3-rc.4");
|
||||
assertEquals(Integer.valueOf(4), version.releaseCandidateVersion);
|
||||
}
|
||||
|
||||
// TODO: remove once x.y.z-rc-n support is dropped after 1.3.0
|
||||
@Test
|
||||
public void testExtractsNonSemverReleaseCandidateVersion() {
|
||||
JcloudsVersion version = new JcloudsVersion("1.2.3-rc-4");
|
||||
assertEquals(Integer.valueOf(4), version.releaseCandidateVersion);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testRecognisesReleaseCandidateSnapshot() {
|
||||
JcloudsVersion version = new JcloudsVersion("1.2.3-rc-4-SNAPSHOT");
|
||||
assertTrue(version.releaseCandidate, "Expected release candidate");
|
||||
assertTrue(version.snapshot, "Expected snapshot");
|
||||
}
|
||||
|
||||
private static class ResourceHidingClassLoader extends ClassLoader {
|
||||
private final ClassLoader delegate;
|
||||
private final List<String> resourcesToHide;
|
||||
|
||||
private ResourceHidingClassLoader(ClassLoader delegate, String... resourcesToHide) {
|
||||
this.delegate = delegate;
|
||||
this.resourcesToHide = ImmutableList.copyOf(resourcesToHide);
|
||||
}
|
||||
|
||||
@Override
|
||||
public InputStream getResourceAsStream(String name) {
|
||||
return (Iterables.contains(resourcesToHide, name)
|
||||
? null
|
||||
: delegate.getResourceAsStream(name));
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1 @@
|
|||
jclouds.version=0.0.0-SNAPSHOT
|
Loading…
Reference in New Issue