diff --git a/build.gradle.kts b/build.gradle.kts index 413e1ae..e482167 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -2,6 +2,7 @@ import me.qoomon.gradle.gitversioning.GitVersioningPluginConfig import me.qoomon.gradle.gitversioning.GitVersioningPluginConfig.CommitVersionDescription import me.qoomon.gradle.gitversioning.GitVersioningPluginConfig.VersionDescription import java.util.Calendar +import java.net.URI plugins { java @@ -18,6 +19,7 @@ group = "com.github.1c-syntax" repositories { mavenCentral() + maven { url = URI("https://jitpack.io") } } val junitVersion = "5.6.0" @@ -26,6 +28,13 @@ dependencies { compileOnly("org.projectlombok", "lombok", lombok.version) + implementation("com.github.hub4j:github-api:github-api-1.114") + implementation("org.slf4j", "slf4j-api", "1.8.0-beta4") + implementation("org.slf4j", "slf4j-simple", "1.8.0-beta4") + + // https://mvnrepository.com/artifact/commons-io/commons-io + implementation("commons-io", "commons-io", "2.7") + testImplementation("org.junit.jupiter", "junit-jupiter-api", junitVersion) testRuntimeOnly("org.junit.jupiter", "junit-jupiter-engine", junitVersion) diff --git a/src/main/java/com/github/_1c_syntax/utils/DownloadHelper.java b/src/main/java/com/github/_1c_syntax/utils/DownloadHelper.java new file mode 100644 index 0000000..8c92225 --- /dev/null +++ b/src/main/java/com/github/_1c_syntax/utils/DownloadHelper.java @@ -0,0 +1,107 @@ +/* + * This file is a part of 1c-syntax utils. + * + * Copyright © 2018-2020 + * Alexey Sosnoviy , Nikita Gryzlov and contributors + * + * SPDX-License-Identifier: LGPL-3.0-or-later + * + * 1c-syntax utils 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 3.0 of the License, or (at your option) any later version. + * + * 1c-syntax utils 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. + * + * You should have received a copy of the GNU Lesser General Public + * License along with 1c-syntax utils. + */ +package com.github._1c_syntax.utils; + +import lombok.experimental.UtilityClass; +import lombok.extern.slf4j.Slf4j; +import org.apache.commons.io.FileUtils; +import org.kohsuke.github.GHAsset; +import org.kohsuke.github.GHRelease; +import org.kohsuke.github.GHRepository; +import org.kohsuke.github.GitHub; + +import java.io.IOException; +import java.net.URL; +import java.nio.file.Path; +import java.util.Optional; + +@UtilityClass +@Slf4j +public class DownloadHelper { + + private final String REPO_PATH = "1c-syntax/bsl-language-server"; + private final String CONTENT_TYPE = "application/zip"; + private final int CONNECTION_TIMEOUT = 900; + + public final String SUPPLY_FOR_WIN = "win"; + public final String SUPPLY_FOR_MAC = "mac"; + public final String SUPPLY_FOR_LINUX = "nix"; + + public Optional getLatestRelease(String token, String supplyVariant, Path pathForSave) { + return getLatestRelease(token, supplyVariant, pathForSave, false); + } + + public Optional getLatestRelease(String token, String supplyVariant, Path pathForSave, boolean prerelease) { + Optional ghAsset; + try { + GitHub github = GitHub.connectUsingOAuth(token); + ghAsset = Optional.ofNullable(github.getRepository(REPO_PATH)) + .flatMap(repo -> { + try { + return getAssetsFromRelease(repo, supplyVariant, prerelease); + } catch (IOException e) { + LOGGER.error("Error finding asset from release", e); + return Optional.empty(); + } + }); + + } catch (IOException e) { + LOGGER.error("Error finding asset from release", e); + ghAsset = Optional.empty(); + } + if (ghAsset.isPresent() && !downloadFromAsset(ghAsset.get(), pathForSave)) { + return Optional.empty(); + } + return ghAsset; + } + + private boolean downloadFromAsset(GHAsset ghAsset, Path path) { + try { + var file = Path.of(path.toString(), ghAsset.getName()).toFile(); + FileUtils.copyURLToFile(new URL(ghAsset.getBrowserDownloadUrl()), file, CONNECTION_TIMEOUT, 0); + } catch (IOException e) { + LOGGER.error("An error occurred while loading", e); + return false; + } + return true; + } + + private Optional getAssetsFromRelease(GHRepository repo, String supplyVariant, boolean prerelease) throws IOException { + var endsName = supplyVariant + ".zip"; + var release = getLatestRelease(repo, prerelease); + if (release.isPresent()) { + return release.get().getAssets().stream() + .filter(ghAsset -> ghAsset.getContentType().equals(CONTENT_TYPE) + && ghAsset.getName().endsWith(endsName)) + .findAny(); + } + return Optional.empty(); + } + + private Optional getLatestRelease(GHRepository repo, boolean prerelease) throws IOException { + return repo.listReleases().toList().stream() + .filter(ghRelease -> prerelease || !ghRelease.isPrerelease()) + .limit(1) + .findAny(); + } + +} diff --git a/src/test/java/com/github/_1c_syntax/utils/DownloadHelperTest.java b/src/test/java/com/github/_1c_syntax/utils/DownloadHelperTest.java new file mode 100644 index 0000000..b8e88f2 --- /dev/null +++ b/src/test/java/com/github/_1c_syntax/utils/DownloadHelperTest.java @@ -0,0 +1,62 @@ +/* + * This file is a part of 1c-syntax utils. + * + * Copyright © 2018-2020 + * Alexey Sosnoviy , Nikita Gryzlov and contributors + * + * SPDX-License-Identifier: LGPL-3.0-or-later + * + * 1c-syntax utils 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 3.0 of the License, or (at your option) any later version. + * + * 1c-syntax utils 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. + * + * You should have received a copy of the GNU Lesser General Public + * License along with 1c-syntax utils. + */ +package com.github._1c_syntax.utils; + +import org.junit.jupiter.api.Test; +import org.kohsuke.github.GHAsset; + +import java.nio.file.Path; +import java.util.Optional; + +import static org.assertj.core.api.Assertions.assertThat; + +public class DownloadHelperTest { + + private final Path BASE_PATH = Path.of("build", "fixture"); + + @Test + public void test_getLatestRelease() { + prepareFolder(BASE_PATH); + var token = System.getenv("GITHUB_TOKEN"); + + var ghAsset = DownloadHelper.getLatestRelease(token, DownloadHelper.SUPPLY_FOR_WIN, BASE_PATH); + checkGHAsset(ghAsset); + + ghAsset = DownloadHelper.getLatestRelease(token, DownloadHelper.SUPPLY_FOR_LINUX, BASE_PATH); + checkGHAsset(ghAsset); + + ghAsset = DownloadHelper.getLatestRelease(token, DownloadHelper.SUPPLY_FOR_MAC, BASE_PATH, true); + checkGHAsset(ghAsset); + } + + void checkGHAsset(Optional ghAsset) { + assertThat(ghAsset).isPresent(); + var file = Path.of(BASE_PATH.toString(), ghAsset.get().getName()).toFile(); + assertThat(file).exists(); + } + + + private void prepareFolder(Path path) { + path.toFile().mkdir(); + } + +}