All Downloads are FREE. Search and download functionalities are using the official Maven repository.

io.quarkus.code.service.GitHubService Maven / Gradle / Ivy

There is a newer version: 37
Show newest version
package io.quarkus.code.service;

import com.google.common.base.Strings;
import io.quarkus.code.config.GitHubConfig;
import io.quarkus.code.model.GitHubCreatedRepository;
import io.quarkus.code.model.GitHubToken;
import io.quarkus.logging.Log;
import jakarta.enterprise.context.ApplicationScoped;
import jakarta.inject.Inject;
import jakarta.ws.rs.WebApplicationException;
import org.eclipse.jgit.api.Git;
import org.eclipse.jgit.api.errors.GitAPIException;
import org.eclipse.jgit.transport.URIish;
import org.eclipse.jgit.transport.UsernamePasswordCredentialsProvider;
import org.eclipse.microprofile.rest.client.inject.RestClient;

import java.io.IOException;
import java.net.URISyntaxException;
import java.nio.file.Path;
import java.util.Objects;
import java.util.logging.Level;
import java.util.logging.Logger;

import static io.quarkus.code.service.GitHubClient.toAuthorization;
import static java.util.function.Predicate.not;

@ApplicationScoped
public class GitHubService {

    @Inject
    private GitHubConfig config;

    @Inject
    @RestClient
    private GitHubOAuthClient oauthClient;

    @Inject
    @RestClient
    private GitHubClient ghClient;

    public String login(String token) {
        try {
            var me = ghClient.getMe(toAuthorization(token));
            return me.getLogin();
        } catch (WebApplicationException wae) {
            Log.warn("Error while getting GH user", wae);
            throw new WebApplicationException("Error while getting GH user");
        }
    }

    public boolean repositoryExists(String login, String token, String repositoryName) {
        checkEnabled();
        requireNonEmpty(token, "token must not be empty.");
        requireNonEmpty(login, "login must not be empty.");
        requireNonEmpty(repositoryName, "repositoryName must not be empty.");
        try {
            var repository = ghClient.getRepo(toAuthorization(token), login, repositoryName);
            return repository.getName().equals(repositoryName);
        } catch (WebApplicationException wae) {
            if (wae.getResponse().getStatus() == 404 || wae.getResponse().getStatus() == 301) {
                return false;
            }
            Log.warn("Error while checking if repository already exists", wae);
            throw new WebApplicationException("Error while checking if repository already exists");
        }
    }

    public GitHubCreatedRepository createRepository(String login, String token, String repositoryName) {
        checkEnabled();
        requireNonEmpty(login, "login must not be empty.");
        requireNonEmpty(token, "token must not be empty.");
        requireNonEmpty(repositoryName, "repositoryName must not be empty.");
        try {
            var createdRepo = ghClient.createRepo(toAuthorization(token),
                    new GitHubClient.GHCreateRepo(repositoryName, "Generated by code.quarkus.io"));
            return new GitHubCreatedRepository(login, createdRepo.getCloneUrl(), createdRepo.getDefaultBranch());
        } catch (WebApplicationException wae) {
            Log.warn("Error while creating the repository", wae);
            throw new WebApplicationException("Error while creating the repository");
        }
    }

    public void push(String ownerName, String token, String initialBranch, String httpTransportUrl, Path path) {
        checkEnabled();
        requireNonEmpty(token, "token must not be empty.");
        requireNonEmpty(httpTransportUrl, "httpTransportUrl must not be empty.");
        requireNonEmpty(ownerName, "ownerName must not be empty.");
        Objects.requireNonNull(path, "path must not be null.");

        try {
            Git.init().setInitialBranch(initialBranch).setDirectory(path.toFile()).call().close();
            try (var repo = Git.open(path.toFile())) {
                repo.add().addFilepattern(".").call();
                repo.commit().setMessage("Initial commit")
                        .setAuthor("quarkusio", "[email protected]")
                        .setCommitter("quarkusio", "[email protected]")
                        .setSign(false)
                        .call();
                var remote = repo.remoteAdd();
                remote.setName("origin");
                remote.setUri(new URIish(httpTransportUrl));
                remote.call();
                var pushCommand = repo.push();
                pushCommand.add("HEAD");
                pushCommand.setRemote("origin");
                pushCommand.setCredentialsProvider(new UsernamePasswordCredentialsProvider(ownerName, token));
                pushCommand.call();
            }
        } catch (GitAPIException | IOException | URISyntaxException e) {
            throw new WebApplicationException("An error occurred while pushing to the git repo", e);
        }
    }

    public GitHubToken fetchAccessToken(String code, String state) throws IOException {
        checkEnabled();
        try {
            var response = oauthClient.getAccessToken(new GitHubOAuthClient.TokenParameter(config.clientId().orElseThrow(),
                    config.clientSecret().orElseThrow(), code, state));
            if (response.containsKey("error")) {
                throw new IOException(response.getFirst("error") + ": " + response.getFirst("error_description"));
            }
            return new GitHubToken(response.getFirst("access_token"), response.getFirst("scope"),
                    response.getFirst("token_type"));
        } catch (WebApplicationException wae) {
            Log.warn("Error while authenticating", wae);
            throw new WebApplicationException("Error while authenticating");
        }
    }

    private void checkEnabled() {
        if (!isEnabled()) {
            throw new IllegalStateException("GitHub is not enabled");
        }
    }

    public boolean isEnabled() {
        return config.clientId().filter(not(Strings::isNullOrEmpty)).isPresent()
                && config.clientSecret().filter(not(Strings::isNullOrEmpty)).isPresent();
    }

    private void requireNonEmpty(String value, String message) {
        if (value.isEmpty()) {
            throw new IllegalArgumentException(message);
        }
    }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy