Skip to content

Commit

Permalink
feat: support theme require halo version. (halo-dev#544)
Browse files Browse the repository at this point in the history
* feat: support theme require halo version.

* fix: com.sun.xml.internal.ws.util does not exist error.

* fix: com.sun.xml.internal.ws.util does not exist error again.

* Update ThemeServiceImpl.java
  • Loading branch information
ruibaby authored Feb 4, 2020
1 parent bb8ee0f commit 08c579a
Show file tree
Hide file tree
Showing 7 changed files with 175 additions and 24 deletions.
18 changes: 18 additions & 0 deletions src/main/java/run/halo/app/exception/ThemeNotSupportException.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
package run.halo.app.exception;

/**
* Theme not support exception.
*
* @author ryanwang
* @date 2020-02-03
*/
public class ThemeNotSupportException extends BadRequestException {

public ThemeNotSupportException(String message) {
super(message);
}

public ThemeNotSupportException(String message, Throwable cause) {
super(message, cause);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,11 @@ public class ThemeProperty {
*/
private String version;

/**
* Require halo version.
*/
private String require;

/**
* Theme author.
*/
Expand Down
47 changes: 42 additions & 5 deletions src/main/java/run/halo/app/service/impl/ThemeServiceImpl.java
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,13 @@
import org.apache.commons.lang3.StringUtils;
import org.eclipse.jgit.api.Git;
import org.eclipse.jgit.api.PullResult;
import org.eclipse.jgit.api.ResetCommand;
import org.eclipse.jgit.api.errors.GitAPIException;
import org.eclipse.jgit.lib.Constants;
import org.eclipse.jgit.lib.Ref;
import org.eclipse.jgit.lib.Repository;
import org.eclipse.jgit.revwalk.RevCommit;
import org.eclipse.jgit.revwalk.RevWalk;
import org.eclipse.jgit.transport.RemoteConfig;
import org.eclipse.jgit.transport.URIish;
import org.springframework.context.ApplicationEventPublisher;
Expand All @@ -31,10 +36,7 @@
import run.halo.app.model.support.ThemeFile;
import run.halo.app.service.OptionService;
import run.halo.app.service.ThemeService;
import run.halo.app.utils.FileUtils;
import run.halo.app.utils.FilenameUtils;
import run.halo.app.utils.GitUtils;
import run.halo.app.utils.HaloUtils;
import run.halo.app.utils.*;

import java.io.IOException;
import java.net.URISyntaxException;
Expand Down Expand Up @@ -477,6 +479,11 @@ public ThemeProperty add(Path themeTmpPath) throws IOException {
throw new AlreadyExistsException("当前安装的主题已存在");
}

// Not support current halo version.
if (StringUtils.isNotEmpty(tmpThemeProperty.getRequire()) && !VersionUtil.compareVersion(HaloConst.HALO_VERSION, tmpThemeProperty.getRequire())) {
throw new ThemeNotSupportException("当前主题仅支持 Halo " + tmpThemeProperty.getRequire() + " 以上的版本");
}

// Copy the temporary path to current theme folder
Path targetThemePath = themeWorkDir.resolve(tmpThemeProperty.getId());
FileUtils.copyFolder(themeTmpPath, targetThemePath);
Expand Down Expand Up @@ -533,6 +540,9 @@ public ThemeProperty update(String themeId) {
try {
pullFromGit(updatingTheme);
} catch (Exception e) {
if (e instanceof ThemeNotSupportException) {
throw (ThemeNotSupportException) e;
}
throw new ThemeUpdateException("主题更新失败!您与主题作者可能同时更改了同一个文件,您也可以尝试删除主题并重新拉取最新的主题", e).setErrorData(themeId);
}

Expand Down Expand Up @@ -579,6 +589,11 @@ public ThemeProperty update(String themeId, MultipartFile file) {
throw new ServiceException("上传的主题包不是该主题的更新包: " + file.getOriginalFilename());
}

// Not support current halo version.
if (StringUtils.isNotEmpty(prepareThemeProperty.getRequire()) && !VersionUtil.compareVersion(HaloConst.HALO_VERSION, prepareThemeProperty.getRequire())) {
throw new ThemeNotSupportException("新版本主题仅支持 Halo " + prepareThemeProperty.getRequire() + " 以上的版本");
}

// Coping new theme files to old theme folder.
FileUtils.copyFolder(preparePath, Paths.get(updatingTheme.getThemePath()));

Expand All @@ -605,6 +620,15 @@ private void pullFromGit(@NonNull ThemeProperty themeProperty) throws IOExceptio

try {
git = GitUtils.openOrInit(Paths.get(themeProperty.getThemePath()));

Repository repository = git.getRepository();

RevWalk revWalk = new RevWalk(repository);

Ref ref = repository.getAllRefs().get(Constants.HEAD);

RevCommit lastCommit = revWalk.parseCommit(ref.getObjectId());

// Force to set remote name
git.remoteRemove().setRemoteName(THEME_PROVIDER_REMOTE_NAME).call();
RemoteConfig remoteConfig = git.remoteAdd()
Expand Down Expand Up @@ -647,6 +671,19 @@ private void pullFromGit(@NonNull ThemeProperty themeProperty) throws IOExceptio

throw new ThemeUpdateException("拉取失败!您与主题作者可能同时更改了同一个文件");
}

// updated successfully.
ThemeProperty updatedThemeProperty = getProperty(Paths.get(themeProperty.getThemePath()));

// Not support current halo version.
if (StringUtils.isNotEmpty(updatedThemeProperty.getRequire()) && !VersionUtil.compareVersion(HaloConst.HALO_VERSION, updatedThemeProperty.getRequire())) {
// reset theme version
git.reset()
.setMode(ResetCommand.ResetType.HARD)
.setRef(lastCommit.getName())
.call();
throw new ThemeNotSupportException("新版本主题仅支持 Halo " + updatedThemeProperty.getRequire() + " 以上的版本");
}
} finally {
GitUtils.closeQuietly(git);
}
Expand Down Expand Up @@ -826,7 +863,7 @@ private Optional<ThemeProperty> getPropertyOfNullable(Path themePath) {
// Set screenshots
getScreenshotsFileName(themePath).ifPresent(screenshotsName ->
themeProperty.setScreenshots(StringUtils.join(optionService.getBlogBaseUrl(),
"/",
"/themes/",
FilenameUtils.getBasename(themeProperty.getThemePath()),
"/",
screenshotsName)));
Expand Down
18 changes: 1 addition & 17 deletions src/main/java/run/halo/app/utils/HaloUtils.java
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
*
* @author ryanwang
* @author johnniang
* @date 2017/12/22
* @date 2017-12-22
*/
@Slf4j
public class HaloUtils {
Expand Down Expand Up @@ -232,22 +232,6 @@ public static String initializeUrlIfBlank(@Nullable String url) {
return String.valueOf(System.currentTimeMillis());
}

/**
* Normalize url.
*
* @param url url must not be blank
* @return normalized url
*/
@NonNull
public static String normalizeUrl(@NonNull String url) {
Assert.hasText(url, "Url must not be blank");

StringUtils.removeEnd(url, "html");
StringUtils.removeEnd(url, "htm");

return SlugUtils.slugify(url);
}

/**
* Gets machine IP address.
*
Expand Down
81 changes: 81 additions & 0 deletions src/main/java/run/halo/app/utils/VersionUtil.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
package run.halo.app.utils;

import cn.hutool.core.util.StrUtil;

import java.util.StringTokenizer;

/**
* @author ryanwang
* @date 2020-02-03
* @see com.sun.xml.internal.ws.util.VersionUtil
*/
public class VersionUtil {

public VersionUtil() {
}

public static int[] getCanonicalVersion(String version) {
int[] canonicalVersion = new int[]{1, 1, 0, 0};
StringTokenizer tokenizer = new StringTokenizer(version, ".");
String token = tokenizer.nextToken();
canonicalVersion[0] = Integer.parseInt(token);
token = tokenizer.nextToken();
StringTokenizer subTokenizer;
if (!token.contains(StrUtil.UNDERLINE)) {
canonicalVersion[1] = Integer.parseInt(token);
} else {
subTokenizer = new StringTokenizer(token, "_");
canonicalVersion[1] = Integer.parseInt(subTokenizer.nextToken());
canonicalVersion[3] = Integer.parseInt(subTokenizer.nextToken());
}

if (tokenizer.hasMoreTokens()) {
token = tokenizer.nextToken();
if (!token.contains(StrUtil.UNDERLINE)) {
canonicalVersion[2] = Integer.parseInt(token);
if (tokenizer.hasMoreTokens()) {
canonicalVersion[3] = Integer.parseInt(tokenizer.nextToken());
}
} else {
subTokenizer = new StringTokenizer(token, "_");
canonicalVersion[2] = Integer.parseInt(subTokenizer.nextToken());
canonicalVersion[3] = Integer.parseInt(subTokenizer.nextToken());
}
}

return canonicalVersion;
}

public static int compare(String version1, String version2) {
int[] canonicalVersion1 = getCanonicalVersion(version1);
int[] canonicalVersion2 = getCanonicalVersion(version2);
if (canonicalVersion1[0] < canonicalVersion2[0]) {
return -1;
} else if (canonicalVersion1[0] > canonicalVersion2[0]) {
return 1;
} else if (canonicalVersion1[1] < canonicalVersion2[1]) {
return -1;
} else if (canonicalVersion1[1] > canonicalVersion2[1]) {
return 1;
} else if (canonicalVersion1[2] < canonicalVersion2[2]) {
return -1;
} else if (canonicalVersion1[2] > canonicalVersion2[2]) {
return 1;
} else if (canonicalVersion1[3] < canonicalVersion2[3]) {
return -1;
} else {
return canonicalVersion1[3] > canonicalVersion2[3] ? 1 : 0;
}
}

/**
* Compare version.
*
* @param current current version.
* @param require require version.
* @return true or false.
*/
public static boolean compareVersion(String current, String require) {
return compare(current, require) >= 0;
}
}
4 changes: 2 additions & 2 deletions src/test/java/run/halo/app/utils/HaloUtilsTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@

import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.RandomUtils;
import org.junit.Assert;
import org.junit.Test;

import java.util.stream.IntStream;
Expand All @@ -15,7 +14,8 @@
* Halo utilities test.
*
* @author johnniang
* @date 3/29/19
* @author ryanwang
* @date 2019-03-29
*/
@Slf4j
public class HaloUtilsTest {
Expand Down
26 changes: 26 additions & 0 deletions src/test/java/run/halo/app/utils/VersionUtilTest.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
package run.halo.app.utils;

import org.junit.Assert;
import org.junit.Test;

/**
* @author ryanwang
* @date 2020-02-03
*/
public class VersionUtilTest {

@Test
public void compareVersion() {
Assert.assertTrue(VersionUtil.compareVersion("1.2.0", "1.1.1"));

Assert.assertTrue(VersionUtil.compareVersion("1.2.1", "1.2.0"));

Assert.assertTrue(VersionUtil.compareVersion("1.2.0", "1.1.1.0"));

Assert.assertTrue(VersionUtil.compareVersion("1.2.0", "0.4.4"));

Assert.assertFalse(VersionUtil.compareVersion("1.1.1", "1.2.0"));

Assert.assertFalse(VersionUtil.compareVersion("0.0.1", "1.2.0"));
}
}

0 comments on commit 08c579a

Please sign in to comment.