DocAsCode.java

package org.docascode.api;

import org.apache.maven.artifact.versioning.DefaultArtifactVersion;
import org.docascode.api.core.errors.DocAsCodeException;
import org.docascode.api.core.DocAsCodeRepository;
import org.docascode.api.core.errors.NotADocAsCodeRepository;
import org.docascode.api.event.Event;
import org.docascode.api.listener.APIEventListener;
import org.eclipse.jgit.lib.Repository;
import org.eclipse.jgit.storage.file.FileRepositoryBuilder;

import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.util.*;

public class DocAsCode extends APIEventListener implements AutoCloseable {
    private DocAsCodeRepository repo;

    private static Map<String,DocAsCode> instances = new HashMap<>();

    private final boolean closeRepo;

    public static List<String> getVersionInformations() throws DocAsCodeException {
        List<String> versionInfos = new ArrayList<>();
        DefaultArtifactVersion docascodeVersion =
                new DefaultArtifactVersion(getVersion());
        versionInfos.add(
                String.format(
                        "DocAsCode version %s",
                        getVersion()));
        versionInfos.add(
                String.format(
                        "Build number %s",
                        getBuildNumber()));
        try {
            String repoVersionString = open().getRepository().getVersion();
            if (repoVersionString != null) {
                DefaultArtifactVersion repoVersion =
                        new DefaultArtifactVersion(repoVersionString);
                if (docascodeVersion.compareTo(repoVersion) > 0) {
                    versionInfos.add(
                            String.format("Your repository was initialized with DocAsCode version %s. You should upgrade your repository. Try 'docascode upgrade'.",
                                    repoVersion));
                } else {
                    if (docascodeVersion.compareTo(repoVersion) < 0) {
                        versionInfos.add(
                                String.format("Your repository was initialized with DocAsCode version %s. You should update your DocAsCode installation.",
                                        repoVersion));
                    } else {
                        versionInfos.add("Your repository is up-to-date w.r.t. your DocAsCode installation");
                    }
                }
            }
        } catch (DocAsCodeException | IllegalArgumentException | NotADocAsCodeRepository e) {
            //Nothing to do. Currently not in a DocAsCode repository.
        }
        return versionInfos;
    }

    @Override
    public void close() {
        if (closeRepo)
            repo.git().close();
    }

    public DocAsCode() throws NotADocAsCodeRepository {
        this(null);
    }

    public static DocAsCode open(File dir) throws NotADocAsCodeRepository {
        if (!instances.containsKey(dir.getAbsolutePath())) {
            FileRepositoryBuilder repositoryBuilder = new FileRepositoryBuilder();
            Repository repository;
            try {
                repository = repositoryBuilder.findGitDir(dir).build();
                DocAsCodeRepository r = new DocAsCodeRepository(repository);
                instances.put(dir.getAbsolutePath(),new DocAsCode(r, true));
            } catch (IOException e) {
                throw new NotADocAsCodeRepository(
                        String.format(
                                "'%s' is not in a Git repository.",
                                dir), e);
            }
        }
        return instances.get(dir.getAbsolutePath());
    }

    private void sanityCheck(DocAsCodeRepository repo) throws DocAsCodeException {
        DefaultArtifactVersion docascodeVersion =
                new DefaultArtifactVersion(DocAsCode.getVersion());
        if (repo.getVersion() !=null ){
            DefaultArtifactVersion repoVersion =
                    new DefaultArtifactVersion(repo.getVersion());
            if (docascodeVersion.compareTo(repoVersion) > 0) {
                log(String.format(
                        "Your repository was initialized with DocAsCode version %s. You should upgrade your repository. Try 'docascode init'.",
                        repoVersion),
                        Event.Level.WARN);
            } else {
                if (docascodeVersion.compareTo(repoVersion) < 0) {
                    log(String.format(
                        "Your repository was initialized with DocAsCode version %s. You should update your DocAsCode installation.",
                        repoVersion),
                        Event.Level.WARN);
                }
            }
        }
    }

    public static DocAsCode open() throws NotADocAsCodeRepository {
        return open(new File(".").getAbsoluteFile());
    }

    public DocAsCode(DocAsCodeRepository repo) throws NotADocAsCodeRepository {
        this(repo, false);
    }

    private DocAsCode(DocAsCodeRepository repo, boolean closeRepo) throws NotADocAsCodeRepository {
        this.repo = repo;
        this.closeRepo = closeRepo;
        this.repo.sanityCheck();
    }

    public static UpdateCommand update(){
        return new UpdateCommand();
    }

    public static InitCommand init(){
        return new InitCommand();
    }

    public AddCommand add(){
        return new AddCommand(repo);
    }

    public BuildCommand build(){
        return new BuildCommand(repo);
    }

    public RemoveCommand remove(){
        return new RemoveCommand(repo);
    }

    public PreCommitCommand preCommit() {
        return new PreCommitCommand(repo);
    }

    public PostCommitCommand postCommit() {
        return new PostCommitCommand(repo);
    }

    public DiffCommand diff() {
        return new DiffCommand(repo);
    }

    public DeployCommand deploy() {
        return new DeployCommand(repo);
    }

    public MergeCommand merge() {return new MergeCommand(repo);}

    public static String getVersion() throws DocAsCodeException {
        Properties properties = new Properties();
        try (InputStream inputStream = DocAsCode.class.getResourceAsStream("/build.properties")){
            properties.load(inputStream);
            return properties.getProperty("version");
        } catch (IOException e) {
            throw new DocAsCodeException("Failed to read Build properties file.", e);
        }
    }

    public static String getBuildNumber() throws DocAsCodeException {
        Properties properties = new Properties();
        try (InputStream inputStream = DocAsCode.class.getResourceAsStream("/build.properties")){
            properties.load(inputStream);
            return properties.getProperty("revision");
        } catch (IOException e) {
            throw new DocAsCodeException("Failed to read Build properties file.", e);
        }
    }

    public static ACIDCommand acid(){
        return new ACIDCommand();
    }

    public static ConvertCommand convert(){
        return new ConvertCommand();
    }

    public DocAsCodeRepository getRepository() throws DocAsCodeException {
        sanityCheck(repo);
        return this.repo;
    }
}