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

com.seeq.utilities.process.SQCommand Maven / Gradle / Ivy

The newest version!
package com.seeq.utilities.process;

import java.io.File;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

import lombok.experimental.UtilityClass;
import lombok.extern.slf4j.Slf4j;

/**
 * Utility for creating processes to call "sq" commands, such as "sq run" and "sq db start". These can be run only in
 * development or testing, not in production! If you need to run "seeq" commands such as "seeq start" or "seeq diag"
 * in production, use {@link PilotCommand}.
 */
@Slf4j
@UtilityClass
public class SQCommand {
    /**
     * Creates a process spawn object whose directory is set to the location of the "nearest" sq file (moving upwards
     * toward the root of the repo)
     *
     * @param command
     *         a string array containing an sq command ie {"database", "--scheme", "test"}
     * @param callingClass
     *         the class object for the class that is calling the command. this is used to properly locate the sq
     *         command in a parent folder.
     * @return a ProcessSpawn object
     */
    public static ProcessSpawn createProcessSpawn(String[] command, Class callingClass) {
        File sqFile = findSqFile(callingClass);
        return createProcessSpawn(command, sqFile);
    }

    /**
     * Creates a process spawn object whose directory is set to an explicit "sq" file location.
     *
     * @param command
     *         a string array containing an sq command ie {"database", "--scheme", "test"}
     * @param sqFile
     *         an explicit "sq" file location. This can be used to call "sq" commands across the boundaries of
     *         directories / Maven modules. Use with caution!
     * @return a ProcessSpawn object
     */
    public static ProcessSpawn createProcessSpawn(String[] command, File sqFile) {
        List commandList = new ArrayList<>();

        if (OperatingSystem.isWindows()) {
            commandList.add(".\\sq.bat");
        } else {
            commandList.add("./sq");
        }

        commandList.addAll(Arrays.asList(command));

        ProcessSpawn sqProcess = new ProcessSpawn(commandList);
        sqProcess.directory(sqFile.getParentFile());
        sqProcess.setUseCmdShell(true);
        return sqProcess;
    }

    public static File findSqFile(Class callingClass) {
        String fileName = "sq";
        // the preferred way to find the proper sq executable is to walk up the directory structure from the given
        // calling class
        File fileOfCurrentClass = new File(callingClass.getProtectionDomain().getCodeSource().getLocation()
                .getFile());
        File folderOfCurrentClass = new File(fileOfCurrentClass.getParent());
        File sqFile = findRoot(folderOfCurrentClass, fileName);
        if (sqFile == null) {
            LOG.debug("no {} found in {} Trying {} instead.", fileName, fileOfCurrentClass,
                    System.getProperty("user.dir"));

            /* maybe the calling class was outside the folder structure of the tree that has sq? This can happen if the
             * calling class was pulled from a jar in the repository (eg ~/.m2/repository/com/seeq/something ) This is
             * known to happen on (at least) osx when invoking "mvn verify" inside appserver/driver/graph.
             *
             * This fallback tries the current directory of the parent process and search again for the command. If this
             * fails, it isn't graceful about trying something else. Oh well, it's not any worse than it was. */
            folderOfCurrentClass = new File(System.getProperty("user.dir"));
            sqFile = findRoot(folderOfCurrentClass, fileName);
        }
        return sqFile;
    }

    /**
     * Recursively looks for a file in a given folder and its parent folders
     *
     * @param folder
     *         a File object with a directory to start the search
     * @param fileName
     *         the name of the file being searched for
     * @return File of the folder that contains the fileName
     */
    private static File findRoot(File folder, String fileName) {
        final File fileEntry = new File(folder, fileName);
        if (fileEntry.isFile()) {
            return fileEntry;
        } else if (folder.getParentFile() != null) {
            return findRoot(folder.getParentFile(), fileName);
        } else {
            return null;
        }
    }

}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy