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

com.heroku.sdk.deploy.lib.resolver.AppNameResolver Maven / Gradle / Ivy

There is a newer version: 3.0.7
Show newest version
package com.heroku.sdk.deploy.lib.resolver;

import org.eclipse.jgit.api.Git;
import org.eclipse.jgit.errors.RepositoryNotFoundException;
import org.eclipse.jgit.lib.Config;

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.nio.file.Path;
import java.util.*;
import java.util.function.Supplier;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class AppNameResolver {

    /**
     * Resolves the Heroku app name based on the given project directory.
     * This uses the already established resolution order from 2.x to ensure backwards compatibility:
     *
     * 1. The heroku.properties file
     * 2. The heroku.appName system property
     * 3. Custom resolution
     * 4. Git remote pointing to an Heroku app
     *
     * @param projectDirectory The projects root directory.
     * @param customResolver A custom resolver for the app name. Most likely a setting from a build tool like Maven or sbt.
     * @return If possible, the resolved app name.
     * @throws IOException Resolving requires IO operations which might fail.
     */
    public static Optional resolve(Path projectDirectory, Supplier> customResolver) throws IOException {
        Optional herokuPropertiesAppName = resolveViaHerokuPropertiesFile(projectDirectory);
        if (herokuPropertiesAppName.isPresent()) {
            return herokuPropertiesAppName;
        }

        Optional systemPropertiesAppName = resolveViaSystemProperty();
        if (systemPropertiesAppName.isPresent()) {
            return systemPropertiesAppName;
        }

        Optional customResolverAppName = customResolver.get();
        if (customResolverAppName.isPresent()) {
            return customResolverAppName;
        }

        return resolveViaHerokuGitRemote(projectDirectory);
    }

    private static Optional resolveViaHerokuGitRemote(Path rootDirectory) throws IOException {
        try {
            Git gitRepo = Git.open(rootDirectory.toFile());
            Config config = gitRepo.getRepository().getConfig();

            for (String remoteName : config.getSubsections("remote")) {
                String remoteUrl = config.getString("remote", remoteName, "url");

                for (Pattern gitRemoteUrlAppNamePattern : GIT_REMOTE_URL_APP_NAME_PATTERNS) {
                    Matcher matcher = gitRemoteUrlAppNamePattern.matcher(remoteUrl);
                    if (matcher.matches()) {
                        return Optional.of(matcher.group(1));
                    }
                }
            }
        } catch (RepositoryNotFoundException e) {
            return Optional.empty();
        }

        return Optional.empty();
    }

    private static Optional resolveViaHerokuPropertiesFile(Path rootDirectory) throws IOException {
        Properties properties = new Properties();

        try {
            properties.load(new FileInputStream(rootDirectory.resolve("heroku.properties").toFile()));
        } catch (FileNotFoundException e) {
            return Optional.empty();
        }

        return Optional.ofNullable(properties.getProperty("heroku.appName"));
    }

    private static Optional resolveViaSystemProperty() {
        return Optional.ofNullable(System.getProperty("heroku.appName"));
    }

    private static final List GIT_REMOTE_URL_APP_NAME_PATTERNS;

    static {
        ArrayList patterns = new ArrayList<>();
        patterns.add(Pattern.compile("https://git\\.heroku\\.com/(.*?)\\.git"));
        patterns.add(Pattern.compile("git@heroku\\.com:(.*?)\\.git"));
        GIT_REMOTE_URL_APP_NAME_PATTERNS = Collections.unmodifiableList(patterns);
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy