mirror of https://github.com/halo-dev/halo
feat: support theme require halo version. (#544)
* 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.javapull/550/head
parent
bb8ee0f074
commit
08c579a095
|
@ -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);
|
||||
}
|
||||
}
|
|
@ -54,6 +54,11 @@ public class ThemeProperty {
|
|||
*/
|
||||
private String version;
|
||||
|
||||
/**
|
||||
* Require halo version.
|
||||
*/
|
||||
private String require;
|
||||
|
||||
/**
|
||||
* Theme author.
|
||||
*/
|
||||
|
|
|
@ -4,8 +4,13 @@ import lombok.extern.slf4j.Slf4j;
|
|||
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;
|
||||
|
@ -31,10 +36,7 @@ import run.halo.app.model.support.HaloConst;
|
|||
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;
|
||||
|
@ -477,6 +479,11 @@ public class ThemeServiceImpl implements ThemeService {
|
|||
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);
|
||||
|
@ -533,6 +540,9 @@ public class ThemeServiceImpl implements ThemeService {
|
|||
try {
|
||||
pullFromGit(updatingTheme);
|
||||
} catch (Exception e) {
|
||||
if (e instanceof ThemeNotSupportException) {
|
||||
throw (ThemeNotSupportException) e;
|
||||
}
|
||||
throw new ThemeUpdateException("主题更新失败!您与主题作者可能同时更改了同一个文件,您也可以尝试删除主题并重新拉取最新的主题", e).setErrorData(themeId);
|
||||
}
|
||||
|
||||
|
@ -579,6 +589,11 @@ public class ThemeServiceImpl implements ThemeService {
|
|||
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()));
|
||||
|
||||
|
@ -605,6 +620,15 @@ public class ThemeServiceImpl implements ThemeService {
|
|||
|
||||
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()
|
||||
|
@ -647,6 +671,19 @@ public class ThemeServiceImpl implements ThemeService {
|
|||
|
||||
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);
|
||||
}
|
||||
|
@ -826,7 +863,7 @@ public class ThemeServiceImpl implements ThemeService {
|
|||
// Set screenshots
|
||||
getScreenshotsFileName(themePath).ifPresent(screenshotsName ->
|
||||
themeProperty.setScreenshots(StringUtils.join(optionService.getBlogBaseUrl(),
|
||||
"/",
|
||||
"/themes/",
|
||||
FilenameUtils.getBasename(themeProperty.getThemePath()),
|
||||
"/",
|
||||
screenshotsName)));
|
||||
|
|
|
@ -17,7 +17,7 @@ import static run.halo.app.model.support.HaloConst.FILE_SEPARATOR;
|
|||
*
|
||||
* @author ryanwang
|
||||
* @author johnniang
|
||||
* @date 2017/12/22
|
||||
* @date 2017-12-22
|
||||
*/
|
||||
@Slf4j
|
||||
public class HaloUtils {
|
||||
|
@ -232,22 +232,6 @@ public class HaloUtils {
|
|||
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.
|
||||
*
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
|
@ -2,7 +2,6 @@ package run.halo.app.utils;
|
|||
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.commons.lang3.RandomUtils;
|
||||
import org.junit.Assert;
|
||||
import org.junit.Test;
|
||||
|
||||
import java.util.stream.IntStream;
|
||||
|
@ -15,7 +14,8 @@ import static org.junit.Assert.assertThat;
|
|||
* Halo utilities test.
|
||||
*
|
||||
* @author johnniang
|
||||
* @date 3/29/19
|
||||
* @author ryanwang
|
||||
* @date 2019-03-29
|
||||
*/
|
||||
@Slf4j
|
||||
public class HaloUtilsTest {
|
||||
|
|
|
@ -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"));
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue