/**
* Copyright (c) 2000-present Liferay, Inc. All rights reserved.
*
* This library 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 2.1 of the License, or (at your option)
* any later version.
*
* This library 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 Lesser General Public License for more
* details.
*/
package com.liferay.portal.release.versions;
import aQute.bnd.osgi.Constants;
import aQute.bnd.version.Version;
import com.liferay.portal.kernel.log.Log;
import com.liferay.portal.kernel.log.LogFactoryUtil;
import com.liferay.portal.kernel.util.ObjectValuePair;
import com.liferay.portal.kernel.util.StringBundler;
import com.liferay.portal.kernel.util.StringPool;
import com.liferay.portal.kernel.util.Validator;
import java.io.IOException;
import java.io.InputStream;
import java.nio.charset.StandardCharsets;
import java.nio.file.FileVisitResult;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.SimpleFileVisitor;
import java.nio.file.attribute.BasicFileAttributes;
import java.util.Arrays;
import java.util.HashSet;
import java.util.Properties;
import java.util.Set;
import org.junit.Assert;
import org.junit.BeforeClass;
import org.junit.Test;
/**
* @author Andrea Di Giorgi
*/
public class ReleaseVersionsTest {
@BeforeClass
public static void setUpClass() {
_portalPath = Paths.get(System.getProperty("user.dir"));
}
@Test
public void testReleaseVersions() throws IOException {
String otherDirName = System.getProperty(
"release.versions.test.other.dir");
Assert.assertTrue(
"Please set the property \"release.versions.test.other.dir\"",
Validator.isNotNull(otherDirName));
final Path otherPath = Paths.get(otherDirName);
Assert.assertTrue(
otherPath + " is not a valid Git repository",
Files.exists(otherPath.resolve(".git")));
final boolean otherRelease = _isRelease(otherPath);
boolean differentTypes = false;
if (otherRelease != _isRelease(_portalPath)) {
differentTypes = true;
}
Assert.assertTrue(
_portalPath + " and " + otherPath + " must be different types",
differentTypes);
final Set<Path> ignorePaths = new HashSet<>(
Arrays.asList(_portalPath.resolve("modules/third-party")));
Files.walkFileTree(
_portalPath,
new SimpleFileVisitor<Path>() {
@Override
public FileVisitResult preVisitDirectory(
Path dirPath, BasicFileAttributes basicFileAttributes)
throws IOException {
if (ignorePaths.contains(dirPath)) {
return FileVisitResult.SKIP_SUBTREE;
}
Path bndBndPath = dirPath.resolve("bnd.bnd");
if (Files.notExists(bndBndPath)) {
return FileVisitResult.CONTINUE;
}
Path bndBndRelativePath = _portalPath.relativize(
bndBndPath);
Path otherBndBndPath = otherPath.resolve(
bndBndRelativePath);
if (Files.notExists(otherBndBndPath)) {
if (_log.isInfoEnabled()) {
_log.info(
"Ignoring " + bndBndRelativePath +
" as it does not exist in " + otherPath);
}
return FileVisitResult.SKIP_SUBTREE;
}
_checkReleaseVersion(
bndBndPath, otherBndBndPath, otherRelease, dirPath);
return FileVisitResult.SKIP_SUBTREE;
}
});
}
private void _checkReleaseVersion(
Path bndBndPath, Path otherBndBndPath, boolean otherRelease,
Path dirPath)
throws IOException {
Properties bndProperties = _loadProperties(bndBndPath);
Properties otherBndProperties = _loadProperties(otherBndBndPath);
String bundleSymbolicName = bndProperties.getProperty(
Constants.BUNDLE_SYMBOLICNAME);
String otherBundleSymbolicName = otherBndProperties.getProperty(
Constants.BUNDLE_SYMBOLICNAME);
Assert.assertEquals(bundleSymbolicName, otherBundleSymbolicName);
ObjectValuePair<Version, Path> versionPathPair = _getVersion(
bndBndPath, bndProperties);
ObjectValuePair<Version, Path> otherVersionPathPair = _getVersion(
otherBndBndPath, otherBndProperties);
ObjectValuePair<Version, Path> masterVersionPair = otherVersionPathPair;
ObjectValuePair<Version, Path> releaseVersionPair = versionPathPair;
if (otherRelease) {
masterVersionPair = versionPathPair;
releaseVersionPair = otherVersionPathPair;
}
Version masterVersion = masterVersionPair.getKey();
Version releaseVersion = releaseVersionPair.getKey();
int delta = 0;
for (int i = 0; i < 3; i++) {
int masterVersionPart = masterVersion.get(i);
int releaseVersionPart = releaseVersion.get(i);
if (masterVersionPart != releaseVersionPart) {
delta = masterVersionPart - releaseVersionPart;
break;
}
}
if ((delta != 0) && (delta != 1)) {
StringBundler sb = new StringBundler(21);
sb.append("Difference in ");
sb.append(Constants.BUNDLE_VERSION);
sb.append(" for ");
sb.append(_portalPath.relativize(dirPath));
sb.append(" between master (");
sb.append(masterVersion);
sb.append(", defined in ");
Path masterVersionPath = masterVersionPair.getValue();
sb.append(masterVersionPath.getFileName());
sb.append(") and release (");
sb.append(releaseVersion);
sb.append(", defined in ");
Path releaseVersionPath = releaseVersionPair.getValue();
sb.append(releaseVersionPath.getFileName());
sb.append(") branches is not allowed. Please ");
Path updateVersionPath;
String updateVersionSeparator;
Path gitRepoPath = _getParentFile(dirPath, ".gitrepo");
if (gitRepoPath != null) {
String gitRepo = _read(gitRepoPath);
if (!gitRepo.contains("mode = pull")) {
gitRepoPath = null;
}
}
if (gitRepoPath != null) {
updateVersionPath = gitRepoPath.getParent();
updateVersionPath = updateVersionPath.getParent();
updateVersionPath = updateVersionPath.resolve(
_getVersionOverrideFileName(dirPath));
updateVersionSeparator = StringPool.EQUAL;
}
else {
updateVersionPath = dirPath.resolve("bnd.bnd");
updateVersionSeparator = ": ";
}
if (Files.exists(updateVersionPath)) {
sb.append("update");
}
else {
sb.append("add");
}
sb.append(" \"");
sb.append(Constants.BUNDLE_VERSION);
sb.append(updateVersionSeparator);
sb.append(releaseVersion);
sb.append("\" in ");
sb.append(_portalPath.relativize(updateVersionPath));
sb.append(" for the master branch.");
Assert.fail(sb.toString());
}
}
private Path _getParentFile(Path dirPath, String fileName) {
while (true) {
Path path = dirPath.resolve(fileName);
if (Files.exists(path)) {
return path;
}
dirPath = dirPath.getParent();
if (dirPath == null) {
return null;
}
}
}
private ObjectValuePair<Version, Path> _getVersion(
Path bndBndPath, Properties bndProperties)
throws IOException {
Path dirPath = bndBndPath.getParent();
Path versionOverridePath = _getParentFile(
dirPath, _getVersionOverrideFileName(dirPath));
if (versionOverridePath != null) {
Properties versionOverrides = _loadProperties(versionOverridePath);
String version = versionOverrides.getProperty(
Constants.BUNDLE_VERSION);
if (Validator.isNotNull(version)) {
return new ObjectValuePair<>(
Version.parseVersion(version), versionOverridePath);
}
}
String version = bndProperties.getProperty(Constants.BUNDLE_VERSION);
return new ObjectValuePair<>(Version.parseVersion(version), bndBndPath);
}
private String _getVersionOverrideFileName(Path dirPath) {
return ".version-override-" + String.valueOf(dirPath.getFileName()) +
".properties";
}
private boolean _isRelease(Path path) {
if (Files.exists(path.resolve("modules/.releng"))) {
return true;
}
return false;
}
private Properties _loadProperties(Path path) throws IOException {
Properties properties = new Properties();
try (InputStream inputStream = Files.newInputStream(path)) {
properties.load(inputStream);
}
return properties;
}
private String _read(Path path) throws IOException {
return new String(Files.readAllBytes(path), StandardCharsets.UTF_8);
}
private static final Log _log = LogFactoryUtil.getLog(
ReleaseVersionsTest.class);
private static Path _portalPath;
}