mirror of https://github.com/halo-dev/halo
* add release access and branch access(#515) * add release and branch access(#515) * always update to latest release(#515) * #515 * #515 * add testcases(#515) * fix 515 * fix 515 * deal with connection refused * disable disk operation related test * fix #592 * fix #515 & #592 * mockito test * ignored network related test * resolve conflictpull/943/head
parent
cd9aa23706
commit
2b99bd599f
12
build.gradle
12
build.gradle
|
@ -69,9 +69,13 @@ ext {
|
||||||
jedisVersion= '3.3.0'
|
jedisVersion= '3.3.0'
|
||||||
zxingVersion = "3.4.0"
|
zxingVersion = "3.4.0"
|
||||||
huaweiObsVersion = "3.19.7"
|
huaweiObsVersion = "3.19.7"
|
||||||
|
githubApiVersion = "1.84"
|
||||||
|
powermockVersion = "1.6.6"
|
||||||
|
mockitoVersion = "1.10.19"
|
||||||
}
|
}
|
||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
|
implementation "org.kohsuke:github-api:$githubApiVersion"
|
||||||
implementation "org.springframework.boot:spring-boot-starter-actuator"
|
implementation "org.springframework.boot:spring-boot-starter-actuator"
|
||||||
implementation "org.springframework.boot:spring-boot-starter-data-jpa"
|
implementation "org.springframework.boot:spring-boot-starter-data-jpa"
|
||||||
implementation "org.springframework.boot:spring-boot-starter-web"
|
implementation "org.springframework.boot:spring-boot-starter-web"
|
||||||
|
@ -131,5 +135,13 @@ dependencies {
|
||||||
|
|
||||||
testImplementation "org.springframework.boot:spring-boot-starter-test"
|
testImplementation "org.springframework.boot:spring-boot-starter-test"
|
||||||
|
|
||||||
|
testCompile group: 'org.mockito', name: 'mockito-all', version: "$mockitoVersion"
|
||||||
|
testCompile group: 'org.powermock', name: 'powermock-api-mockito', version: "$powermockVersion"
|
||||||
|
testCompile group: 'org.powermock', name: 'powermock-module-junit4', version: "$powermockVersion"
|
||||||
|
|
||||||
developmentOnly "org.springframework.boot:spring-boot-devtools"
|
developmentOnly "org.springframework.boot:spring-boot-devtools"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
test {
|
||||||
|
useJUnitPlatform()
|
||||||
|
}
|
|
@ -175,10 +175,39 @@ public class ThemeController {
|
||||||
return themeService.fetch(uri);
|
return themeService.fetch(uri);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@PostMapping("fetchingBranches")
|
||||||
|
@ApiOperation("Fetches all branches")
|
||||||
|
public List<ThemeProperty> fetchBranches(@RequestParam("uri") String uri) {
|
||||||
|
return themeService.fetchBranches(uri);
|
||||||
|
}
|
||||||
|
|
||||||
|
@PostMapping("fetchingReleases")
|
||||||
|
@ApiOperation("Fetches all releases")
|
||||||
|
public List<ThemeProperty> fetchReleases(@RequestParam("uri") String uri) {
|
||||||
|
return themeService.fetchReleases(uri);
|
||||||
|
}
|
||||||
|
|
||||||
|
@GetMapping("fetchingRelease")
|
||||||
|
@ApiOperation("Fetches a specific release")
|
||||||
|
public ThemeProperty fetchRelease(@RequestParam("uri") String uri, @RequestParam("tag") String tagName) {
|
||||||
|
return themeService.fetchRelease(uri, tagName);
|
||||||
|
}
|
||||||
|
|
||||||
|
@GetMapping("fetchBranch")
|
||||||
|
@ApiOperation("Fetch specific branch")
|
||||||
|
public ThemeProperty fetchBranch(@RequestParam("uri") String uri, @RequestParam("branch") String branchName) {
|
||||||
|
return themeService.fetchBranch(uri, branchName);
|
||||||
|
}
|
||||||
|
|
||||||
|
@GetMapping("fetchLatestRelease")
|
||||||
|
@ApiOperation("Fetch latest release")
|
||||||
|
public ThemeProperty fetchLatestRelease(@RequestParam("uri") String uri) {
|
||||||
|
return themeService.fetchLatestRelease(uri);
|
||||||
|
}
|
||||||
|
|
||||||
@PutMapping("fetching/{themeId}")
|
@PutMapping("fetching/{themeId}")
|
||||||
@ApiOperation("Upgrades theme by remote")
|
@ApiOperation("Upgrades theme by remote")
|
||||||
public ThemeProperty updateThemeByFetching(@PathVariable("themeId") String themeId) {
|
public ThemeProperty updateThemeByFetching(@PathVariable("themeId") String themeId) {
|
||||||
|
|
||||||
return themeService.update(themeId);
|
return themeService.update(themeId);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -88,13 +88,23 @@ public interface ThemeService {
|
||||||
/**
|
/**
|
||||||
* Theme provider remote name.
|
* Theme provider remote name.
|
||||||
*/
|
*/
|
||||||
String THEME_PROVIDER_REMOTE_NAME = "theme-provider";
|
String THEME_PROVIDER_REMOTE_NAME = "origin";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Default remote branch name.
|
* Default remote branch name.
|
||||||
*/
|
*/
|
||||||
String DEFAULT_REMOTE_BRANCH = "master";
|
String DEFAULT_REMOTE_BRANCH = "master";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Key to access the zip file url which is in the http response
|
||||||
|
*/
|
||||||
|
String ZIP_FILE_KEY = "zipball_url";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Key to access the tag name which is in the http response
|
||||||
|
*/
|
||||||
|
String TAG_KEY = "tag_name";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get theme property by theme id.
|
* Get theme property by theme id.
|
||||||
*
|
*
|
||||||
|
@ -303,6 +313,53 @@ public interface ThemeService {
|
||||||
@NonNull
|
@NonNull
|
||||||
ThemeProperty fetch(@NonNull String uri);
|
ThemeProperty fetch(@NonNull String uri);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Fetches the latest release
|
||||||
|
*
|
||||||
|
* @param uri theme remote uri must not be null
|
||||||
|
* @return theme property
|
||||||
|
*/
|
||||||
|
@NonNull
|
||||||
|
ThemeProperty fetchLatestRelease(@NonNull String uri);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Fetches all the branches info
|
||||||
|
*
|
||||||
|
* @param uri theme remote uri must not be null
|
||||||
|
* @return list of theme properties
|
||||||
|
*/
|
||||||
|
@NonNull
|
||||||
|
List<ThemeProperty> fetchBranches(@NonNull String uri);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Fetches all the release info
|
||||||
|
*
|
||||||
|
* @param uri theme remote uri must not be null
|
||||||
|
* @return list of theme properties
|
||||||
|
*/
|
||||||
|
@NonNull
|
||||||
|
List<ThemeProperty> fetchReleases(@NonNull String uri);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Fetches a specific release
|
||||||
|
*
|
||||||
|
* @param uri theme remote uri must not be null
|
||||||
|
* @param tagName release tag name must not be null
|
||||||
|
* @return theme property
|
||||||
|
*/
|
||||||
|
@NonNull
|
||||||
|
ThemeProperty fetchRelease(@NonNull String uri, @NonNull String tagName);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Fetches a specific branch (clone)
|
||||||
|
*
|
||||||
|
* @param uri theme remote uri must not be null
|
||||||
|
* @param branchName wanted branch must not be null
|
||||||
|
* @return theme property
|
||||||
|
*/
|
||||||
|
@NonNull
|
||||||
|
ThemeProperty fetchBranch(@NonNull String uri, @NonNull String branchName);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Reloads themes
|
* Reloads themes
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -493,9 +493,9 @@ public class ThemeServiceImpl implements ThemeService {
|
||||||
if (StringUtils.endsWithIgnoreCase(uri, ".zip")) {
|
if (StringUtils.endsWithIgnoreCase(uri, ".zip")) {
|
||||||
downloadZipAndUnzip(uri, themeTmpPath);
|
downloadZipAndUnzip(uri, themeTmpPath);
|
||||||
} else {
|
} else {
|
||||||
uri = StringUtils.appendIfMissingIgnoreCase(uri, ".git", ".git");
|
String repoUrl = StringUtils.appendIfMissingIgnoreCase(uri, ".git", ".git");
|
||||||
// Clone from git
|
// Clone from git
|
||||||
GitUtils.cloneFromGit(uri, themeTmpPath);
|
GitUtils.cloneFromGit(repoUrl, themeTmpPath);
|
||||||
}
|
}
|
||||||
|
|
||||||
return add(themeTmpPath);
|
return add(themeTmpPath);
|
||||||
|
@ -506,6 +506,125 @@ public class ThemeServiceImpl implements ThemeService {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ThemeProperty fetchBranch(String uri, String branchName) {
|
||||||
|
Assert.hasText(uri, "Theme remote uri must not be blank");
|
||||||
|
|
||||||
|
Path tmpPath = null;
|
||||||
|
|
||||||
|
try {
|
||||||
|
// Create temp path
|
||||||
|
tmpPath = FileUtils.createTempDirectory();
|
||||||
|
// Create temp path
|
||||||
|
Path themeTmpPath = tmpPath.resolve(HaloUtils.randomUUIDWithoutDash());
|
||||||
|
|
||||||
|
String repoUrl = StringUtils.appendIfMissingIgnoreCase(uri, ".git", ".git");
|
||||||
|
GitUtils.cloneFromGit(repoUrl, themeTmpPath, branchName);
|
||||||
|
|
||||||
|
return add(themeTmpPath);
|
||||||
|
} catch (IOException | GitAPIException e) {
|
||||||
|
throw new ServiceException("主题拉取失败 " + uri, e);
|
||||||
|
} finally {
|
||||||
|
FileUtils.deleteFolderQuietly(tmpPath);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ThemeProperty fetchRelease(@NonNull String uri, @NonNull String tagName) {
|
||||||
|
Assert.hasText(uri, "Theme remote uri must not be blank");
|
||||||
|
Assert.hasText(tagName, "Theme remote tagName must not be blank");
|
||||||
|
|
||||||
|
Path tmpPath = null;
|
||||||
|
try {
|
||||||
|
tmpPath = FileUtils.createTempDirectory();
|
||||||
|
|
||||||
|
Path themeTmpPath = tmpPath.resolve(HaloUtils.randomUUIDWithoutDash());
|
||||||
|
|
||||||
|
Map<String, Object> releaseInfo = GithubUtils.getRelease(uri, tagName);
|
||||||
|
|
||||||
|
if (releaseInfo == null) {
|
||||||
|
throw new ServiceException("主题拉取失败" + uri);
|
||||||
|
}
|
||||||
|
|
||||||
|
String zipUrl = (String) releaseInfo.get(ZIP_FILE_KEY);
|
||||||
|
|
||||||
|
downloadZipAndUnzip(zipUrl, themeTmpPath);
|
||||||
|
|
||||||
|
return add(themeTmpPath);
|
||||||
|
} catch (IOException e) {
|
||||||
|
throw new ServiceException("主题拉取失败 " + uri, e);
|
||||||
|
} finally {
|
||||||
|
FileUtils.deleteFolderQuietly(tmpPath);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ThemeProperty fetchLatestRelease(@NonNull String uri) {
|
||||||
|
Assert.hasText(uri, "Theme remote uri must not be blank");
|
||||||
|
|
||||||
|
Path tmpPath = null;
|
||||||
|
try {
|
||||||
|
tmpPath = FileUtils.createTempDirectory();
|
||||||
|
|
||||||
|
Path themeTmpPath = tmpPath.resolve(HaloUtils.randomUUIDWithoutDash());
|
||||||
|
|
||||||
|
Map<String, Object> releaseInfo = GithubUtils.getLatestRelease(uri);
|
||||||
|
|
||||||
|
if (releaseInfo == null) {
|
||||||
|
throw new ServiceException("主题拉取失败" + uri);
|
||||||
|
}
|
||||||
|
|
||||||
|
String zipUrl = (String) releaseInfo.get(ZIP_FILE_KEY);
|
||||||
|
|
||||||
|
downloadZipAndUnzip(zipUrl, themeTmpPath);
|
||||||
|
|
||||||
|
return add(themeTmpPath);
|
||||||
|
} catch (IOException e) {
|
||||||
|
throw new ServiceException("主题拉取失败 " + uri, e);
|
||||||
|
} finally {
|
||||||
|
FileUtils.deleteFolderQuietly(tmpPath);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<ThemeProperty> fetchBranches(String uri) {
|
||||||
|
Assert.hasText(uri, "Theme remote uri must not be blank");
|
||||||
|
|
||||||
|
String repoUrl = StringUtils.appendIfMissingIgnoreCase(uri, ".git",".git");
|
||||||
|
List<String> branches = GitUtils.getAllBranches(repoUrl);
|
||||||
|
|
||||||
|
List<ThemeProperty> themeProperties = new ArrayList<>();
|
||||||
|
|
||||||
|
branches.forEach(branch -> {
|
||||||
|
ThemeProperty themeProperty = new ThemeProperty();
|
||||||
|
themeProperty.setBranch(branch);
|
||||||
|
themeProperties.add(themeProperty);
|
||||||
|
});
|
||||||
|
|
||||||
|
return themeProperties;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<ThemeProperty> fetchReleases(@NonNull String uri) {
|
||||||
|
Assert.hasText(uri, "Theme remote uri must not be blank");
|
||||||
|
|
||||||
|
List<String> releases = GithubUtils.getReleases(uri);
|
||||||
|
|
||||||
|
List<ThemeProperty> themeProperties = new ArrayList<>();
|
||||||
|
|
||||||
|
if (releases == null) {
|
||||||
|
throw new ServiceException("主题拉取失败");
|
||||||
|
}
|
||||||
|
|
||||||
|
releases.forEach(tagName -> {
|
||||||
|
ThemeProperty themeProperty = new ThemeProperty();
|
||||||
|
themeProperty.setBranch(tagName);
|
||||||
|
themeProperties.add(themeProperty);
|
||||||
|
});
|
||||||
|
|
||||||
|
return themeProperties;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void reload() {
|
public void reload() {
|
||||||
eventPublisher.publishEvent(new ThemeUpdatedEvent(this));
|
eventPublisher.publishEvent(new ThemeUpdatedEvent(this));
|
||||||
|
@ -519,6 +638,7 @@ public class ThemeServiceImpl implements ThemeService {
|
||||||
|
|
||||||
try {
|
try {
|
||||||
pullFromGit(updatingTheme);
|
pullFromGit(updatingTheme);
|
||||||
|
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
if (e instanceof ThemeNotSupportException) {
|
if (e instanceof ThemeNotSupportException) {
|
||||||
throw (ThemeNotSupportException) e;
|
throw (ThemeNotSupportException) e;
|
||||||
|
@ -597,7 +717,7 @@ public class ThemeServiceImpl implements ThemeService {
|
||||||
|
|
||||||
// Get branch
|
// Get branch
|
||||||
String branch = StringUtils.isBlank(themeProperty.getBranch()) ?
|
String branch = StringUtils.isBlank(themeProperty.getBranch()) ?
|
||||||
DEFAULT_REMOTE_BRANCH : themeProperty.getBranch();
|
DEFAULT_REMOTE_BRANCH : themeProperty.getBranch();
|
||||||
|
|
||||||
Git git = null;
|
Git git = null;
|
||||||
|
|
||||||
|
@ -606,6 +726,13 @@ public class ThemeServiceImpl implements ThemeService {
|
||||||
|
|
||||||
Repository repository = git.getRepository();
|
Repository repository = git.getRepository();
|
||||||
|
|
||||||
|
// Add all changes
|
||||||
|
git.add()
|
||||||
|
.addFilepattern(".")
|
||||||
|
.call();
|
||||||
|
// Commit the changes
|
||||||
|
git.commit().setMessage("Commit by halo automatically").call();
|
||||||
|
|
||||||
RevWalk revWalk = new RevWalk(repository);
|
RevWalk revWalk = new RevWalk(repository);
|
||||||
|
|
||||||
Ref ref = repository.findRef(Constants.HEAD);
|
Ref ref = repository.findRef(Constants.HEAD);
|
||||||
|
@ -617,38 +744,31 @@ public class ThemeServiceImpl implements ThemeService {
|
||||||
// Force to set remote name
|
// Force to set remote name
|
||||||
git.remoteRemove().setRemoteName(THEME_PROVIDER_REMOTE_NAME).call();
|
git.remoteRemove().setRemoteName(THEME_PROVIDER_REMOTE_NAME).call();
|
||||||
RemoteConfig remoteConfig = git.remoteAdd()
|
RemoteConfig remoteConfig = git.remoteAdd()
|
||||||
.setName(THEME_PROVIDER_REMOTE_NAME)
|
.setName(THEME_PROVIDER_REMOTE_NAME)
|
||||||
.setUri(new URIish(themeProperty.getRepo()))
|
.setUri(new URIish(themeProperty.getRepo()))
|
||||||
.call();
|
.call();
|
||||||
|
|
||||||
// Add all changes
|
|
||||||
git.add()
|
|
||||||
.addFilepattern(".")
|
|
||||||
.call();
|
|
||||||
// Commit the changes
|
|
||||||
git.commit().setMessage("Commit by halo automatically").call();
|
|
||||||
|
|
||||||
// Check out to specified branch
|
// Check out to specified branch
|
||||||
if (!StringUtils.equalsIgnoreCase(branch, git.getRepository().getBranch())) {
|
if (!StringUtils.equalsIgnoreCase(branch, git.getRepository().getBranch())) {
|
||||||
boolean present = git.branchList()
|
boolean present = git.branchList()
|
||||||
.call()
|
.call()
|
||||||
.stream()
|
.stream()
|
||||||
.map(Ref::getName)
|
.map(Ref::getName)
|
||||||
.anyMatch(name -> StringUtils.equalsIgnoreCase(name, branch));
|
.anyMatch(name -> StringUtils.equalsIgnoreCase(name, branch));
|
||||||
|
|
||||||
git.checkout()
|
git.checkout()
|
||||||
.setCreateBranch(true)
|
.setCreateBranch(true)
|
||||||
.setForced(!present)
|
.setForced(!present)
|
||||||
.setName(branch)
|
.setName(branch)
|
||||||
.call();
|
.call();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Pull with rebasing
|
// Pull with rebasing
|
||||||
PullResult pullResult = git.pull()
|
PullResult pullResult = git.pull()
|
||||||
.setRemote(remoteConfig.getName())
|
.setRemote(remoteConfig.getName())
|
||||||
.setRemoteBranchName(branch)
|
.setRemoteBranchName(branch)
|
||||||
.setRebase(true)
|
.setRebase(true)
|
||||||
.call();
|
.call();
|
||||||
|
|
||||||
if (!pullResult.isSuccessful()) {
|
if (!pullResult.isSuccessful()) {
|
||||||
log.debug("Rebase result: [{}]", pullResult.getRebaseResult());
|
log.debug("Rebase result: [{}]", pullResult.getRebaseResult());
|
||||||
|
@ -657,6 +777,9 @@ public class ThemeServiceImpl implements ThemeService {
|
||||||
throw new ThemeUpdateException("拉取失败!您与主题作者可能同时更改了同一个文件");
|
throw new ThemeUpdateException("拉取失败!您与主题作者可能同时更改了同一个文件");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
String latestTagName = (String) GithubUtils.getLatestRelease(themeProperty.getRepo()).get(TAG_KEY);
|
||||||
|
git.checkout().setName(latestTagName).call();
|
||||||
|
|
||||||
// updated successfully.
|
// updated successfully.
|
||||||
ThemeProperty updatedThemeProperty = getProperty(Paths.get(themeProperty.getThemePath()));
|
ThemeProperty updatedThemeProperty = getProperty(Paths.get(themeProperty.getThemePath()));
|
||||||
|
|
||||||
|
@ -664,9 +787,9 @@ public class ThemeServiceImpl implements ThemeService {
|
||||||
if (StringUtils.isNotEmpty(updatedThemeProperty.getRequire()) && !VersionUtil.compareVersion(HaloConst.HALO_VERSION, updatedThemeProperty.getRequire())) {
|
if (StringUtils.isNotEmpty(updatedThemeProperty.getRequire()) && !VersionUtil.compareVersion(HaloConst.HALO_VERSION, updatedThemeProperty.getRequire())) {
|
||||||
// reset theme version
|
// reset theme version
|
||||||
git.reset()
|
git.reset()
|
||||||
.setMode(ResetCommand.ResetType.HARD)
|
.setMode(ResetCommand.ResetType.HARD)
|
||||||
.setRef(lastCommit.getName())
|
.setRef(lastCommit.getName())
|
||||||
.call();
|
.call();
|
||||||
throw new ThemeNotSupportException("新版本主题仅支持 Halo " + updatedThemeProperty.getRequire() + " 以上的版本");
|
throw new ThemeNotSupportException("新版本主题仅支持 Halo " + updatedThemeProperty.getRequire() + " 以上的版本");
|
||||||
}
|
}
|
||||||
} finally {
|
} finally {
|
||||||
|
@ -696,7 +819,6 @@ public class ThemeServiceImpl implements ThemeService {
|
||||||
}
|
}
|
||||||
|
|
||||||
log.debug("Downloaded [{}]", zipUrl);
|
log.debug("Downloaded [{}]", zipUrl);
|
||||||
|
|
||||||
// Unzip it
|
// Unzip it
|
||||||
FileUtils.unzip(downloadResponse.getBody(), targetPath);
|
FileUtils.unzip(downloadResponse.getBody(), targetPath);
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,6 +10,7 @@ import run.halo.app.exception.ForbiddenException;
|
||||||
import java.io.*;
|
import java.io.*;
|
||||||
import java.nio.file.*;
|
import java.nio.file.*;
|
||||||
import java.nio.file.attribute.BasicFileAttributes;
|
import java.nio.file.attribute.BasicFileAttributes;
|
||||||
|
import java.util.Arrays;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
import java.util.stream.Stream;
|
import java.util.stream.Stream;
|
||||||
|
@ -131,6 +132,19 @@ public class FileUtils {
|
||||||
|
|
||||||
zipEntry = zis.getNextEntry();
|
zipEntry = zis.getNextEntry();
|
||||||
}
|
}
|
||||||
|
File targetDir = targetPath.toFile();
|
||||||
|
List<File> files = Arrays.asList(targetDir.listFiles());
|
||||||
|
// if zip file has root file
|
||||||
|
if (files.size() == 1 && files.get(0).isDirectory()) {
|
||||||
|
String rootPath = files.get(0).toPath().toString();
|
||||||
|
String rootFile = rootPath.substring(rootPath.lastIndexOf("/", rootPath.length() - 1) + 1,rootPath.length());
|
||||||
|
List<File> propertyFiles = Arrays.asList(files.get(0).listFiles());
|
||||||
|
for (File propertyFile : propertyFiles) {
|
||||||
|
String filePath = propertyFile.toPath().toString();
|
||||||
|
String destPath = filePath.replace(rootFile, "");
|
||||||
|
Files.copy(propertyFile.toPath(), Paths.get(destPath));
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -3,13 +3,17 @@ package run.halo.app.utils;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.eclipse.jgit.api.Git;
|
import org.eclipse.jgit.api.Git;
|
||||||
import org.eclipse.jgit.api.errors.GitAPIException;
|
import org.eclipse.jgit.api.errors.GitAPIException;
|
||||||
|
import org.eclipse.jgit.api.errors.InvalidRemoteException;
|
||||||
|
import org.eclipse.jgit.api.errors.TransportException;
|
||||||
import org.eclipse.jgit.errors.RepositoryNotFoundException;
|
import org.eclipse.jgit.errors.RepositoryNotFoundException;
|
||||||
|
import org.eclipse.jgit.lib.Ref;
|
||||||
import org.eclipse.jgit.storage.file.WindowCacheConfig;
|
import org.eclipse.jgit.storage.file.WindowCacheConfig;
|
||||||
import org.springframework.lang.NonNull;
|
import org.springframework.lang.NonNull;
|
||||||
import org.springframework.util.Assert;
|
import org.springframework.util.Assert;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.nio.file.Path;
|
import java.nio.file.Path;
|
||||||
|
import java.util.*;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Git utilities.
|
* Git utilities.
|
||||||
|
@ -59,6 +63,43 @@ public class GitUtils {
|
||||||
return git;
|
return git;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static void cloneFromGit(@NonNull String repoUrl, @NonNull Path targetPath, @NonNull String branchName) throws GitAPIException {
|
||||||
|
Assert.hasText(repoUrl, "Repository remote url must not be blank");
|
||||||
|
Assert.notNull(targetPath, "Target path must not be null");
|
||||||
|
|
||||||
|
Git git = null;
|
||||||
|
try {
|
||||||
|
git = Git.cloneRepository()
|
||||||
|
.setURI(repoUrl)
|
||||||
|
.setDirectory(targetPath.toFile())
|
||||||
|
.setBranchesToClone(Arrays.asList("refs/heads/" + branchName))
|
||||||
|
.setBranch("refs/heads/" + branchName)
|
||||||
|
.call();
|
||||||
|
} finally {
|
||||||
|
closeQuietly(git);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static List<String> getAllBranches(@NonNull String repoUrl) {
|
||||||
|
List<String> branches = new ArrayList<String>();
|
||||||
|
try {
|
||||||
|
Collection<Ref> refs = Git.lsRemoteRepository()
|
||||||
|
.setHeads(true)
|
||||||
|
.setRemote(repoUrl)
|
||||||
|
.call();
|
||||||
|
for (Ref ref : refs) {
|
||||||
|
branches.add(ref.getName().substring(ref.getName().lastIndexOf("/") + 1, ref.getName().length()));
|
||||||
|
}
|
||||||
|
} catch (InvalidRemoteException e) {
|
||||||
|
log.warn("Git url is not valid", e);
|
||||||
|
} catch (TransportException e) {
|
||||||
|
log.warn("Transport exception", e);
|
||||||
|
} catch (GitAPIException e) {
|
||||||
|
log.warn("Git api exception", e);
|
||||||
|
}
|
||||||
|
return branches;
|
||||||
|
}
|
||||||
|
|
||||||
public static void closeQuietly(Git git) {
|
public static void closeQuietly(Git git) {
|
||||||
if (git != null) {
|
if (git != null) {
|
||||||
git.getRepository().close();
|
git.getRepository().close();
|
||||||
|
|
|
@ -0,0 +1,368 @@
|
||||||
|
package run.halo.app.utils;
|
||||||
|
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.apache.commons.lang3.StringUtils;
|
||||||
|
import org.kohsuke.github.*;
|
||||||
|
import run.halo.app.service.ThemeService;
|
||||||
|
|
||||||
|
import java.io.FileNotFoundException;
|
||||||
|
import java.util.*;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* GithubUtils send request to api.github.com
|
||||||
|
*
|
||||||
|
* @author bigbang019
|
||||||
|
* @date 2020-05-31
|
||||||
|
*/
|
||||||
|
@Slf4j
|
||||||
|
public class GithubUtils {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The prefix need to remove
|
||||||
|
*/
|
||||||
|
static final String PREFIX = "https://github.com/";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get latest release
|
||||||
|
* @param uri repository url must not be null
|
||||||
|
* @return the map object containning tagname and zipfile url
|
||||||
|
*/
|
||||||
|
public static Map<String, Object> getLatestRelease(String uri) {
|
||||||
|
String repoUrl = StringUtils.removeStartIgnoreCase(uri, PREFIX);
|
||||||
|
|
||||||
|
try {
|
||||||
|
GithubLatestRelease githubLatestRelease = new GithubLatestRelease(repoUrl);
|
||||||
|
|
||||||
|
Thread thread = new Thread(githubLatestRelease);
|
||||||
|
|
||||||
|
thread.start();
|
||||||
|
|
||||||
|
thread.join(10 * 1000);
|
||||||
|
|
||||||
|
return githubLatestRelease.result;
|
||||||
|
} catch (InterruptedException e) {
|
||||||
|
log.warn("Interrupted", e);
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get release information
|
||||||
|
* @param uri repository url must not be null
|
||||||
|
* @return list of tagname of releases
|
||||||
|
*/
|
||||||
|
public static List<String> getReleases(String uri) {
|
||||||
|
String repoUrl = StringUtils.removeStartIgnoreCase(uri, PREFIX);
|
||||||
|
|
||||||
|
try {
|
||||||
|
GithubReleases githubReleases = new GithubReleases(repoUrl);
|
||||||
|
|
||||||
|
Thread thread = new Thread(githubReleases);
|
||||||
|
|
||||||
|
thread.start();
|
||||||
|
|
||||||
|
thread.join(10 * 1000);
|
||||||
|
|
||||||
|
return githubReleases.result;
|
||||||
|
} catch (InterruptedException e) {
|
||||||
|
log.warn("Interrupted", e);
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get release information
|
||||||
|
* @param uri repository url must not be null
|
||||||
|
* @param tagName tag must not be null
|
||||||
|
* @return the map object containning tagname and zipfile url
|
||||||
|
*/
|
||||||
|
public static Map<String, Object> getRelease(String uri, String tagName) {
|
||||||
|
String repoUrl = StringUtils.removeStartIgnoreCase(uri, PREFIX);
|
||||||
|
|
||||||
|
try {
|
||||||
|
GithubRelease githubRelease = new GithubRelease(repoUrl, tagName);
|
||||||
|
|
||||||
|
Thread thread = new Thread(githubRelease);
|
||||||
|
|
||||||
|
thread.start();
|
||||||
|
|
||||||
|
thread.join(10 * 1000);
|
||||||
|
|
||||||
|
return githubRelease.result;
|
||||||
|
} catch (InterruptedException e) {
|
||||||
|
log.warn("Interrupted", e);
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the content of theme.yaml/theme.yml
|
||||||
|
* @param uri repository url must not be null
|
||||||
|
* @param branch branch must not be null
|
||||||
|
* @return content of the file
|
||||||
|
*/
|
||||||
|
public static String accessThemeProperty(String uri, String branch) {
|
||||||
|
String repoUrl = StringUtils.removeStartIgnoreCase(uri, PREFIX);
|
||||||
|
|
||||||
|
try {
|
||||||
|
GithubFile githubFile = new GithubFile(repoUrl, branch);
|
||||||
|
|
||||||
|
Thread thread = new Thread(githubFile);
|
||||||
|
|
||||||
|
thread.start();
|
||||||
|
|
||||||
|
thread.join(10 * 1000);
|
||||||
|
|
||||||
|
return githubFile.result;
|
||||||
|
} catch (InterruptedException e) {
|
||||||
|
log.warn("Interrupted", e);
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static class GithubRelease implements Runnable {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The return result is zip url and tag name etc.
|
||||||
|
*/
|
||||||
|
private HashMap<String, Object> result;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* should be in format of "username/reponame"
|
||||||
|
*/
|
||||||
|
private String repoUrl;
|
||||||
|
|
||||||
|
private String tagName;
|
||||||
|
|
||||||
|
public GithubRelease(String repoUrl, String tagName) {
|
||||||
|
this.repoUrl = repoUrl;
|
||||||
|
this.tagName = tagName;
|
||||||
|
result = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
while (true) {
|
||||||
|
try {
|
||||||
|
GitHub gitHub = GitHub.connectAnonymously();
|
||||||
|
GHRepository ghRepository = gitHub.getRepository(repoUrl);
|
||||||
|
List<GHRelease> ghReleaseList = ghRepository.getReleases();
|
||||||
|
|
||||||
|
if (ghReleaseList.size() == 0) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
Optional<GHRelease> res = ghReleaseList.stream()
|
||||||
|
.filter(release -> StringUtils.equalsIgnoreCase(release.getTagName(), tagName))
|
||||||
|
.findFirst();
|
||||||
|
|
||||||
|
if (res.isPresent()) {
|
||||||
|
GHRelease ghRelease = res.get();
|
||||||
|
|
||||||
|
result = new HashMap<String, Object>() {
|
||||||
|
{
|
||||||
|
put(ThemeService.ZIP_FILE_KEY, ghRelease.getZipballUrl());
|
||||||
|
put(ThemeService.TAG_KEY, ghRelease.getTagName());
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
|
||||||
|
} catch (Exception e) {
|
||||||
|
if (e instanceof HttpException) {
|
||||||
|
int code = ((HttpException) e).getResponseCode();
|
||||||
|
if (code != -1) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
Thread.sleep(2000);
|
||||||
|
} catch (InterruptedException e) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static class GithubReleases implements Runnable {
|
||||||
|
|
||||||
|
private List<String> result;
|
||||||
|
|
||||||
|
private String repoUrl;
|
||||||
|
|
||||||
|
public GithubReleases(String repoUrl) {
|
||||||
|
this.repoUrl = repoUrl;
|
||||||
|
result = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
while (true) {
|
||||||
|
try {
|
||||||
|
GitHub gitHub = GitHub.connectAnonymously();
|
||||||
|
GHRepository ghRepository = gitHub.getRepository(repoUrl);
|
||||||
|
List<GHRelease> ghReleaseList = ghRepository.getReleases();
|
||||||
|
|
||||||
|
result = new ArrayList<String>();
|
||||||
|
|
||||||
|
for (GHRelease ghRelease : ghReleaseList) {
|
||||||
|
result.add(ghRelease.getTagName());
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
|
||||||
|
} catch (Exception e) {
|
||||||
|
if (e instanceof HttpException) {
|
||||||
|
int code = ((HttpException) e).getResponseCode();
|
||||||
|
if (code != -1) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
Thread.sleep(2000);
|
||||||
|
} catch (InterruptedException e) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static class GithubLatestRelease implements Runnable {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The return result is zip url and tag name etc.
|
||||||
|
*/
|
||||||
|
private HashMap<String, Object> result;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* should be in format of "username/reponame"
|
||||||
|
*/
|
||||||
|
private String repoUrl;
|
||||||
|
|
||||||
|
public GithubLatestRelease(String repoUrl) {
|
||||||
|
this.repoUrl = repoUrl;
|
||||||
|
result = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
while (true) {
|
||||||
|
try {
|
||||||
|
GitHub gitHub = GitHub.connectAnonymously();
|
||||||
|
GHRepository ghRepository = gitHub.getRepository(repoUrl);
|
||||||
|
List<GHRelease> ghReleaseList = ghRepository.getReleases();
|
||||||
|
|
||||||
|
if (ghReleaseList.size() == 0) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
GHRelease ghRelease = ghReleaseList.get(0);
|
||||||
|
|
||||||
|
result = new HashMap<String, Object>() {
|
||||||
|
{
|
||||||
|
put(ThemeService.ZIP_FILE_KEY, ghRelease.getZipballUrl());
|
||||||
|
put(ThemeService.TAG_KEY, ghRelease.getTagName());
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
break;
|
||||||
|
|
||||||
|
} catch (Exception e) {
|
||||||
|
if (e instanceof HttpException) {
|
||||||
|
int code = ((HttpException) e).getResponseCode();
|
||||||
|
if (code != -1) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
Thread.sleep(2000);
|
||||||
|
} catch (InterruptedException e) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static class GithubFile implements Runnable {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* result is file content
|
||||||
|
*/
|
||||||
|
private String result;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* should be in format of "username/reponame"
|
||||||
|
*/
|
||||||
|
private String repoUrl;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* the branch name
|
||||||
|
*/
|
||||||
|
private String branch;
|
||||||
|
|
||||||
|
public GithubFile(String repoUrl, String branch) {
|
||||||
|
this.repoUrl = repoUrl;
|
||||||
|
this.branch = branch;
|
||||||
|
result = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
while (true) {
|
||||||
|
try {
|
||||||
|
GitHub gitHub = GitHub.connectAnonymously();
|
||||||
|
|
||||||
|
GHRepository ghRepository = gitHub.getRepository(repoUrl);
|
||||||
|
|
||||||
|
GHContent ghContent = null;
|
||||||
|
|
||||||
|
for (String themePropertyFile : ThemeService.THEME_PROPERTY_FILE_NAMES) {
|
||||||
|
|
||||||
|
try {
|
||||||
|
ghContent = ghRepository.getFileContent(themePropertyFile, branch);
|
||||||
|
} catch (FileNotFoundException e) {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ghContent == null) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
result = ghContent.getContent();
|
||||||
|
|
||||||
|
break;
|
||||||
|
} catch (Exception e) {
|
||||||
|
if (e instanceof HttpException) {
|
||||||
|
int code = ((HttpException) e).getResponseCode();
|
||||||
|
if (code != -1) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
} else {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
Thread.sleep(2000);
|
||||||
|
} catch (InterruptedException e) {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -5,7 +5,7 @@ import org.junit.Test;
|
||||||
import org.junit.runner.RunWith;
|
import org.junit.runner.RunWith;
|
||||||
import org.mockito.InjectMocks;
|
import org.mockito.InjectMocks;
|
||||||
import org.mockito.Mock;
|
import org.mockito.Mock;
|
||||||
import org.mockito.junit.MockitoJUnitRunner;
|
import org.mockito.runners.MockitoJUnitRunner;
|
||||||
import run.halo.app.cache.AbstractStringCacheStore;
|
import run.halo.app.cache.AbstractStringCacheStore;
|
||||||
import run.halo.app.model.entity.Option;
|
import run.halo.app.model.entity.Option;
|
||||||
import run.halo.app.model.properties.QiniuOssProperties;
|
import run.halo.app.model.properties.QiniuOssProperties;
|
||||||
|
|
|
@ -0,0 +1,130 @@
|
||||||
|
package run.halo.app.service.impl;
|
||||||
|
|
||||||
|
|
||||||
|
import org.junit.Assert;
|
||||||
|
import org.junit.Before;
|
||||||
|
import org.junit.Test;
|
||||||
|
import org.junit.runner.RunWith;
|
||||||
|
import org.mockito.*;
|
||||||
|
import org.powermock.api.mockito.PowerMockito;
|
||||||
|
import org.powermock.core.classloader.annotations.PrepareForTest;
|
||||||
|
import org.powermock.modules.junit4.PowerMockRunner;
|
||||||
|
import org.springframework.context.ApplicationEventPublisher;
|
||||||
|
import org.springframework.web.client.RestTemplate;
|
||||||
|
import run.halo.app.cache.AbstractStringCacheStore;
|
||||||
|
import run.halo.app.config.properties.HaloProperties;
|
||||||
|
import run.halo.app.handler.theme.config.ThemeConfigResolver;
|
||||||
|
import run.halo.app.handler.theme.config.support.ThemeProperty;
|
||||||
|
import run.halo.app.service.OptionService;
|
||||||
|
import run.halo.app.utils.FileUtils;
|
||||||
|
import run.halo.app.utils.GitUtils;
|
||||||
|
import run.halo.app.utils.GithubUtils;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
import java.nio.file.Path;
|
||||||
|
import java.util.*;
|
||||||
|
|
||||||
|
@RunWith(PowerMockRunner.class)
|
||||||
|
@PrepareForTest({GitUtils.class, GithubUtils.class, FileUtils.class, ThemeServiceImpl.class})
|
||||||
|
public class ThemeServiceImplTest {
|
||||||
|
|
||||||
|
@Mock
|
||||||
|
private HaloProperties haloProperties;
|
||||||
|
|
||||||
|
@Mock
|
||||||
|
private OptionService optionService;
|
||||||
|
|
||||||
|
@Mock
|
||||||
|
private AbstractStringCacheStore cacheStore;
|
||||||
|
|
||||||
|
@Mock
|
||||||
|
private ThemeConfigResolver themeConfigResolver;
|
||||||
|
|
||||||
|
@Mock
|
||||||
|
private RestTemplate restTemplate;
|
||||||
|
|
||||||
|
@Mock
|
||||||
|
private ApplicationEventPublisher eventPublisher;
|
||||||
|
|
||||||
|
@InjectMocks
|
||||||
|
public ThemeServiceImpl themeService;
|
||||||
|
|
||||||
|
@Before
|
||||||
|
public void setUp() throws Exception {
|
||||||
|
//Static Method
|
||||||
|
PowerMockito.mockStatic(GithubUtils.class);
|
||||||
|
PowerMockito.mockStatic(GitUtils.class);
|
||||||
|
PowerMockito.mockStatic(FileUtils.class);
|
||||||
|
|
||||||
|
PowerMockito.doReturn(Arrays.asList("master", "dev")).when(GitUtils.class, "getAllBranches", Mockito.any(String.class));
|
||||||
|
PowerMockito.doNothing().when(GitUtils.class, "cloneFromGit", Mockito.any(String.class), Mockito.any(Path.class));
|
||||||
|
|
||||||
|
PowerMockito.doReturn("propertyContent").when(GithubUtils.class, "accessThemeProperty", Mockito.any(String.class), Mockito.any(String.class));
|
||||||
|
|
||||||
|
PowerMockito.doReturn(new File("tmpPath").toPath()).when(FileUtils.class, "createTempDirectory");
|
||||||
|
PowerMockito.doNothing().when(FileUtils.class, "deleteFolderQuietly", Mockito.any(Path.class));
|
||||||
|
|
||||||
|
//Method
|
||||||
|
themeService = PowerMockito.spy(new ThemeServiceImpl(haloProperties, optionService, cacheStore, themeConfigResolver, restTemplate, eventPublisher));
|
||||||
|
|
||||||
|
Mockito.doNothing().when(eventPublisher).publishEvent(Mockito.any(String.class));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void fetchGitTest() throws Exception {
|
||||||
|
String uri = "https://github.com/halo-dev/halo-theme-pinghsu";
|
||||||
|
PowerMockito.doNothing().when(themeService, "downloadZipAndUnzip", Mockito.any(String.class), Mockito.any(Path.class));
|
||||||
|
PowerMockito.doReturn(new ThemeProperty()).when(themeService, "add", Mockito.any(Path.class));
|
||||||
|
ThemeProperty themeProperty = themeService.fetch(uri);
|
||||||
|
Assert.assertNotNull(themeProperty);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void fetchZipTest() throws Exception {
|
||||||
|
String uri = "https://github.com/halo-dev/halo-theme-pinghsu/archive/master.zip";
|
||||||
|
PowerMockito.doNothing().when(themeService, "downloadZipAndUnzip", Mockito.any(String.class), Mockito.any(Path.class));
|
||||||
|
PowerMockito.doReturn(new ThemeProperty()).when(themeService, "add", Mockito.any(Path.class));
|
||||||
|
ThemeProperty themeProperty = themeService.fetch(uri);
|
||||||
|
Assert.assertNotNull(themeProperty);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void fetchBranchesTest() {
|
||||||
|
String uri = "https://github.com/halo-dev/halo-theme-hux";
|
||||||
|
|
||||||
|
List<ThemeProperty> themeProperties = themeService.fetchBranches(uri);
|
||||||
|
|
||||||
|
Assert.assertNotNull(themeProperties);
|
||||||
|
Assert.assertEquals(themeProperties.size(), 2);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void fetchBranchTest() throws Exception {
|
||||||
|
String uri = "https://github.com/halo-dev/halo-theme-casper";
|
||||||
|
String branch = "master";
|
||||||
|
PowerMockito.doNothing().when(themeService, "downloadZipAndUnzip", Mockito.any(String.class), Mockito.any(Path.class));
|
||||||
|
PowerMockito.doReturn(new ThemeProperty()).when(themeService, "add", Mockito.any(Path.class));
|
||||||
|
ThemeProperty themeProperty = themeService.fetchBranch(uri, branch);
|
||||||
|
Assert.assertNotNull(themeProperty);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void fetchLatestReleaseTest() throws Exception {
|
||||||
|
String uri = "https://github.com/halo-dev/halo-theme-casper";
|
||||||
|
PowerMockito.doNothing().when(themeService, "downloadZipAndUnzip", Mockito.any(String.class), Mockito.any(Path.class));
|
||||||
|
PowerMockito.doReturn(new ThemeProperty()).when(themeService, "add", Mockito.any(Path.class));
|
||||||
|
ThemeProperty themeProperty = themeService.fetchLatestRelease(uri);
|
||||||
|
Assert.assertNotNull(themeProperty);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void updateTest() throws Exception {
|
||||||
|
PowerMockito.doNothing().when(themeService, "downloadZipAndUnzip", Mockito.any(String.class), Mockito.any(Path.class));
|
||||||
|
PowerMockito.doReturn(new ThemeProperty()).when(themeService, "add", Mockito.any(Path.class));
|
||||||
|
PowerMockito.doNothing().when(themeService, "pullFromGit", Mockito.any(ThemeProperty.class));
|
||||||
|
PowerMockito.doReturn(new ThemeProperty()).when(themeService, "getThemeOfNonNullBy", Mockito.any(String.class));
|
||||||
|
ThemeProperty themeProperty = themeService.update("String");
|
||||||
|
Assert.assertNotNull(themeProperty);
|
||||||
|
}
|
||||||
|
}
|
|
@ -7,10 +7,7 @@ import org.eclipse.jgit.api.errors.GitAPIException;
|
||||||
import org.eclipse.jgit.errors.RepositoryNotFoundException;
|
import org.eclipse.jgit.errors.RepositoryNotFoundException;
|
||||||
import org.eclipse.jgit.transport.RemoteConfig;
|
import org.eclipse.jgit.transport.RemoteConfig;
|
||||||
import org.eclipse.jgit.transport.URIish;
|
import org.eclipse.jgit.transport.URIish;
|
||||||
import org.junit.After;
|
import org.junit.*;
|
||||||
import org.junit.Before;
|
|
||||||
import org.junit.Ignore;
|
|
||||||
import org.junit.Test;
|
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.net.URISyntaxException;
|
import java.net.URISyntaxException;
|
||||||
|
@ -80,6 +77,21 @@ public class GitTest {
|
||||||
git.close();
|
git.close();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@Ignore
|
||||||
|
public void getAllBranchesTest() {
|
||||||
|
List<String> branches = GitUtils.getAllBranches("https://github.com/halo-dev/halo-theme-hux.git");
|
||||||
|
Assert.assertNotNull(branches);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@Ignore
|
||||||
|
public void getAllBranchesWithInvalidURL() {
|
||||||
|
List<String> branches = GitUtils.getAllBranches("https://github.com/halo-dev/halo-theme.git");
|
||||||
|
Assert.assertNotNull(branches);
|
||||||
|
Assert.assertEquals(branches.size(), 0);
|
||||||
|
}
|
||||||
|
|
||||||
private Git cloneRepository() throws GitAPIException {
|
private Git cloneRepository() throws GitAPIException {
|
||||||
return Git.cloneRepository()
|
return Git.cloneRepository()
|
||||||
.setURI("https://github.com/halo-dev/halo-theme-pinghsu.git")
|
.setURI("https://github.com/halo-dev/halo-theme-pinghsu.git")
|
||||||
|
|
|
@ -0,0 +1,46 @@
|
||||||
|
package run.halo.app.utils;
|
||||||
|
|
||||||
|
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.junit.Assert;
|
||||||
|
import org.junit.Ignore;
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
@Slf4j
|
||||||
|
public class GithubUtilsTest {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@Ignore
|
||||||
|
public void getLatestReleasesWithValidURL() {
|
||||||
|
Map<String, Object> map = GithubUtils.getLatestRelease("https://github.com/halo-dev/halo-theme-hux");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@Ignore
|
||||||
|
public void getLatestReleasesWithInvalidURL() {
|
||||||
|
Map<String, Object> map = GithubUtils.getLatestRelease("https://github.com/halo-dev/halo-theme-hu");
|
||||||
|
Assert.assertNull(map);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@Ignore
|
||||||
|
public void accessThemePropertyWithValidURL() {
|
||||||
|
String content = GithubUtils.accessThemeProperty("https://github.com/halo-dev/halo-theme-hux", "master");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@Ignore
|
||||||
|
public void accessThemePropertyWithInvalidURL() {
|
||||||
|
String content = GithubUtils.accessThemeProperty("https://github.com/halo-dev/halo-theme-hu", "master");
|
||||||
|
Assert.assertNull(content);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@Ignore
|
||||||
|
public void getReleasesTest() {
|
||||||
|
List<String> list = GithubUtils.getReleases("https://github.com/halo-dev/halo-theme-hux");
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue