Skip to content

Commit

Permalink
chore: make RepositoryManager a composite ReleaseRepository (#711)
Browse files Browse the repository at this point in the history
The public interface of `RepositoryManager` is basically that of `ReleaseRepository`. Its purpose is to combine the different sources for game releases and hide where exactly a release is coming from.

Thus, make it implement `ReleaseRepository` and use the interface in more places instead of the specific class.

Also, drop the `...Adapter` suffixes as I'm not sure what they were intended to express anymore. The interface is called `ReleaseRepository` (with Adapter), and the two classes are implementing that interface.

In addition, this also deletes the unused class `JobResult`.
  • Loading branch information
skaldarnar authored Nov 26, 2023
1 parent da5d3b2 commit 1410948
Show file tree
Hide file tree
Showing 9 changed files with 36 additions and 41 deletions.
12 changes: 6 additions & 6 deletions src/main/java/org/terasology/launcher/LauncherConfiguration.java
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
package org.terasology.launcher;

import org.terasology.launcher.game.GameManager;
import org.terasology.launcher.repositories.RepositoryManager;
import org.terasology.launcher.repositories.ReleaseRepository;
import org.terasology.launcher.settings.Settings;

import java.nio.file.Path;
Expand All @@ -22,17 +22,17 @@ public class LauncherConfiguration {
private final Path downloadDirectory;
private final Settings launcherSettings;
private final GameManager gameManager;
private final RepositoryManager repositoryManager;
private final ReleaseRepository releaseRepository;

public LauncherConfiguration(final Path launcherDirectory,
final Path downloadDirectory,
final Settings launcherSettings,
GameManager gameManager, RepositoryManager repositoryManager) {
GameManager gameManager, ReleaseRepository releaseRepository) {
this.launcherDirectory = launcherDirectory;
this.downloadDirectory = downloadDirectory;
this.launcherSettings = launcherSettings;
this.gameManager = gameManager;
this.repositoryManager = repositoryManager;
this.releaseRepository = releaseRepository;
}

public Path getLauncherDirectory() {
Expand All @@ -51,7 +51,7 @@ public GameManager getGameManager() {
return gameManager;
}

public RepositoryManager getRepositoryManager() {
return repositoryManager;
public ReleaseRepository getReleaseRepository() {
return releaseRepository;
}
}
6 changes: 3 additions & 3 deletions src/main/java/org/terasology/launcher/LauncherInitTask.java
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
import org.slf4j.LoggerFactory;
import org.terasology.launcher.game.GameManager;
import org.terasology.launcher.model.LauncherVersion;
import org.terasology.launcher.repositories.RepositoryManager;
import org.terasology.launcher.repositories.CombinedRepository;
import org.terasology.launcher.settings.LauncherSettingsValidator;
import org.terasology.launcher.settings.Settings;
import org.terasology.launcher.ui.Dialogs;
Expand Down Expand Up @@ -92,7 +92,7 @@ protected LauncherConfiguration call() {
updateMessage(I18N.getLabel("splash_fetchReleases"));
logger.info("Fetching game releases ...");
// implicitly fetches game releases and cache them
final RepositoryManager repositoryManager = new RepositoryManager(client);
final CombinedRepository releaseRepository = new CombinedRepository(client);

// implicitly scans the game directory for installed games and cache them
final GameManager gameManager = new GameManager(cacheDirectory, gameDirectory);
Expand All @@ -111,7 +111,7 @@ protected LauncherConfiguration call() {
downloadDirectory,
launcherSettings,
gameManager,
repositoryManager);
releaseRepository);
} catch (LauncherStartFailedException e) {
logger.warn("Could not configure launcher.");
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@

package org.terasology.launcher.repositories;

import com.google.common.collect.Lists;
import com.google.common.collect.Sets;
import com.google.gson.Gson;
import okhttp3.OkHttpClient;
Expand All @@ -14,7 +15,7 @@
import java.util.Set;
import java.util.stream.Collectors;

public class RepositoryManager {
public class CombinedRepository implements ReleaseRepository {

private final Set<GameRelease> releases;

Expand All @@ -23,11 +24,11 @@ public class RepositoryManager {
*
* @param httpClient the HTTP client to be used for remote requests
*/
public RepositoryManager(OkHttpClient httpClient) {
public CombinedRepository(OkHttpClient httpClient) {
JenkinsClient client = new JenkinsClient(httpClient, new Gson());

ReleaseRepository omegaNightly = new JenkinsRepositoryAdapter(Profile.OMEGA, Build.NIGHTLY, client);
ReleaseRepository github = new GithubRepositoryAdapter(httpClient);
ReleaseRepository omegaNightly = new JenkinsRepository(Profile.OMEGA, Build.NIGHTLY, client);
ReleaseRepository github = new GithubRepository(httpClient);

Set<ReleaseRepository> all = Sets.newHashSet(github, omegaNightly);

Expand All @@ -46,4 +47,8 @@ public Set<GameRelease> getReleases() {
return releases;
}

@Override
public List<GameRelease> fetchReleases() {
return Lists.newArrayList(getReleases());
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -29,13 +29,13 @@
import java.util.Optional;
import java.util.stream.Collectors;

public class GithubRepositoryAdapter implements ReleaseRepository {
public class GithubRepository implements ReleaseRepository {

private static final Logger logger = LoggerFactory.getLogger(GithubRepositoryAdapter.class);
private static final Logger logger = LoggerFactory.getLogger(GithubRepository.class);

private GitHub github;

public GithubRepositoryAdapter(final OkHttpClient httpClient) {
public GithubRepository(final OkHttpClient httpClient) {
try {
github = GitHubBuilder.fromEnvironment()
.withConnector(new OkHttpConnector(httpClient))
Expand Down Expand Up @@ -86,7 +86,7 @@ public List<GameRelease> fetchReleases() {
final GHRepository repository = github.getRepository("MovingBlocks/Terasology");
final List<GHRelease> githubReleases = repository.listReleases().toList();
final List<GameRelease> releases = githubReleases.stream()
.map(GithubRepositoryAdapter::fromGithubRelease)
.map(GithubRepository::fromGithubRelease)
.filter(Objects::nonNull)
.collect(Collectors.toList());
logger.debug("Github rate limit: {}", github.getRateLimit());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,9 +30,9 @@
* However, this means that we are doing {@code n + 1} API calls for fetching {@code n} release packages on each
* launcher start.
*/
class JenkinsRepositoryAdapter implements ReleaseRepository {
class JenkinsRepository implements ReleaseRepository {

private static final Logger logger = LoggerFactory.getLogger(JenkinsRepositoryAdapter.class);
private static final Logger logger = LoggerFactory.getLogger(JenkinsRepository.class);

private static final String BASE_URL = "http://jenkins.terasology.io/teraorg/job/Terasology/";

Expand All @@ -53,7 +53,7 @@ class JenkinsRepositoryAdapter implements ReleaseRepository {

private final URL apiUrl;

JenkinsRepositoryAdapter(Profile profile, Build buildProfile, JenkinsClient client) {
JenkinsRepository(Profile profile, Build buildProfile, JenkinsClient client) {
this.client = client;
this.buildProfile = buildProfile;
this.profile = profile;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
* <p>
* Each release repository provides a list of game releases. This is a common API for potentially different sources,
* such as GitHub, Jenkins build servers, or other similar. A new release repository has to be added in-code by
* implementing this interface and registering it in the {@link RepositoryManager}.
* implementing this interface and registering it in the {@link CombinedRepository}.
* </p>
*/
public interface ReleaseRepository {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@

package org.terasology.launcher.ui;

import com.google.common.collect.Sets;
import javafx.animation.Transition;
import javafx.beans.binding.Bindings;
import javafx.beans.binding.ObjectBinding;
Expand Down Expand Up @@ -43,7 +44,7 @@
import org.terasology.launcher.model.GameRelease;
import org.terasology.launcher.model.Profile;
import org.terasology.launcher.model.ReleaseMetadata;
import org.terasology.launcher.repositories.RepositoryManager;
import org.terasology.launcher.repositories.ReleaseRepository;
import org.terasology.launcher.settings.Settings;
import org.terasology.launcher.tasks.DeleteTask;
import org.terasology.launcher.tasks.DownloadTask;
Expand Down Expand Up @@ -213,12 +214,11 @@ public void initialize() {
private void initComboBoxes() {
final ObjectBinding<ObservableList<GameRelease>> releases = Bindings.createObjectBinding(() -> {
LauncherConfiguration cfg = config.getValue();
if (cfg == null || cfg.getRepositoryManager() == null) {
if (cfg == null || cfg.getReleaseRepository() == null) {
return FXCollections.emptyObservableList();
} else {
RepositoryManager mngr = config.getValue().getRepositoryManager();

Set<GameRelease> onlineReleases = mngr.getReleases();
ReleaseRepository repository = config.getValue().getReleaseRepository();
Set<GameRelease> onlineReleases = Sets.newHashSet(repository.fetchReleases());
// Create dummy game release objects from locally installed games.
// We need this in case of running the launcher in "offline" mode
// and the list of game releases fetched via the repository manager
Expand Down
10 changes: 0 additions & 10 deletions src/main/java/org/terasology/launcher/util/JobResult.java

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@
import static org.junit.jupiter.api.Assertions.assertTrue;

@DisplayName("JenkinsRepositoryAdapter#fetchReleases() should")
class JenkinsRepositoryAdapterTest {
class JenkinsRepositoryTest {

static Gson gson;
static Jenkins.ApiResult validResult;
Expand All @@ -56,7 +56,7 @@ static Stream<Arguments> incompleteResults() {
@DisplayName("handle null Jenkins response gracefully")
void handleNullJenkinsResponseGracefully() {
final JenkinsClient nullClient = new StubJenkinsClient(url -> null, url -> null);
final JenkinsRepositoryAdapter adapter = new JenkinsRepositoryAdapter(Profile.OMEGA, Build.STABLE, nullClient);
final JenkinsRepository adapter = new JenkinsRepository(Profile.OMEGA, Build.STABLE, nullClient);
assertTrue(adapter.fetchReleases().isEmpty());
}

Expand All @@ -67,7 +67,7 @@ void skipBuildsWithoutVersionInfo() {

final JenkinsClient stubClient = new StubJenkinsClient(url -> validResult, url -> emptyVersionInfo);

final JenkinsRepositoryAdapter adapter = new JenkinsRepositoryAdapter(Profile.OMEGA, Build.STABLE, stubClient);
final JenkinsRepository adapter = new JenkinsRepository(Profile.OMEGA, Build.STABLE, stubClient);

assertTrue(adapter.fetchReleases().isEmpty());
}
Expand All @@ -93,7 +93,7 @@ void processValidResponseCorrectly() {
final ReleaseMetadata releaseMetadata = new ReleaseMetadata("", new Date(1604285977306L));
final GameRelease expected = new GameRelease(id, expectedArtifactUrl, releaseMetadata);

final JenkinsRepositoryAdapter adapter = new JenkinsRepositoryAdapter(Profile.OMEGA, Build.STABLE, stubClient);
final JenkinsRepository adapter = new JenkinsRepository(Profile.OMEGA, Build.STABLE, stubClient);

assertEquals(1, adapter.fetchReleases().size());
assertAll(
Expand All @@ -108,7 +108,7 @@ void processValidResponseCorrectly() {
@MethodSource("incompleteResults")
void skipIncompatibleApiResults(Jenkins.ApiResult incompleteResult) {
final JenkinsClient stubClient = new StubJenkinsClient(url -> incompleteResult, url -> null);
final JenkinsRepositoryAdapter adapter = new JenkinsRepositoryAdapter(Profile.OMEGA, Build.STABLE, stubClient);
final JenkinsRepository adapter = new JenkinsRepository(Profile.OMEGA, Build.STABLE, stubClient);
assertTrue(adapter.fetchReleases().isEmpty());
}
}

0 comments on commit 1410948

Please sign in to comment.