001package com.dev9.mvnwatcher;
002
003/*
004 * Copyright 2001-2005 The Apache Software Foundation.
005 *
006 * Licensed under the Apache License, Version 2.0 (the "License");
007 * you may not use this file except in compliance with the License.
008 * You may obtain a copy of the License at
009 *
010 *      http://www.apache.org/licenses/LICENSE-2.0
011 *
012 * Unless required by applicable law or agreed to in writing, software
013 * distributed under the License is distributed on an "AS IS" BASIS,
014 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
015 * See the License for the specific language governing permissions and
016 * limitations under the License.
017 */
018
019import com.google.common.annotations.VisibleForTesting;
020import org.apache.maven.plugin.AbstractMojo;
021import org.apache.maven.plugin.MojoExecutionException;
022import org.apache.maven.plugin.logging.Log;
023import org.apache.maven.plugins.annotations.Mojo;
024
025import java.io.File;
026import java.io.IOException;
027import java.nio.file.Path;
028import java.nio.file.Paths;
029import java.util.ArrayList;
030import java.util.List;
031
032/**
033 * Only goal: watch a directory for changes.
034 *
035 * @goal watch
036 */
037@Mojo(name = "Watcher")
038public class WatcherMojo extends AbstractMojo {
039    /**
040     * Location of the Java sources.
041     *
042     * @parameter default-value="${project.build.sourceDirectory}"
043     * @required
044     */
045    public File sourceDirectory;
046
047    /**
048     * Location of the resources.
049     *
050     * @parameter default-value="${project.build.resources[0].directory}"
051     * @required
052     */
053    public File resourcesDirectory;
054
055    /**
056     * This is typically the root folder for the project, holding the pom.xml file.
057     *
058     * @parameter default-value="${project.basedir}"
059     * @readonly
060     */
061    public File basedir;
062
063    /**
064     * Typically, this is the target directory.
065     *
066     * @parameter default-value="${project.build.directory}"
067     * @readonly
068     */
069    public File directory;
070
071    /**
072     * Typically, this is the target directory.
073     *
074     * @parameter default-value="${project.build.directory}/${project.build.finalName}.${project.packaging}"
075     * @readonly
076     */
077
078    public File finalName;
079
080    /**
081     * Defaults to false.  Set to true for WatcherMojo to self-terminate (useful for testing)
082     */
083    @VisibleForTesting
084    public boolean terminate = false;
085
086    /**
087     * @parameter
088     */
089    public List<Task> tasks;
090
091
092    public void createTargetDirectoryIfNotExists() {
093
094        if (!basedir.exists())
095            throw new IllegalArgumentException("Can't create target directory, no basedir defined.");
096
097        if (directory == null) {
098            directory = Paths.get(basedir.getAbsolutePath(), "target").toFile();
099        }
100
101        if (!directory.exists()) {
102            directory.mkdirs();
103        }
104
105    }
106
107    public List<Task> getDefaultTasks(Path base) {
108        if (basedir == null)
109            basedir = base.toFile();
110
111        if (sourceDirectory == null) {
112            sourceDirectory = Paths.get(base.toFile().getAbsolutePath(), "src", "main", "java").toFile();
113        }
114
115        if (resourcesDirectory == null) {
116            resourcesDirectory = Paths.get(base.toFile().getAbsolutePath(), "src", "main", "resources").toFile();
117        }
118
119        if (finalName == null)
120            finalName = Paths.get(base.toFile().getAbsolutePath(), "target", "demo-0.0.1-SNAPSHOT.jar").toFile();
121
122        createTargetDirectoryIfNotExists();
123
124        System.out.println("Using default spring-boot configuration.");
125
126        List<Task> result = new ArrayList<>();
127
128        Task mvnBuild = new Task(
129                "mvn",
130                java.util.Arrays.asList("resources:resources", "compiler:compile", "jar:jar", "spring-boot:repackage"),
131                Paths.get(basedir.getAbsolutePath(), "target", "mvnrunner-build.log").toFile(),
132                basedir.toPath());
133
134        Task javaBuild = new Task(
135                "java",
136                java.util.Arrays.asList("-jar", finalName.getAbsolutePath()),
137                Paths.get(directory.getAbsolutePath(), "mvnrunner-app.log").toFile(),
138                directory.toPath()
139        );
140
141        result.add(mvnBuild);
142        result.add(javaBuild);
143
144        return result;
145    }
146
147    public void execute() throws MojoExecutionException {
148
149        Log log = getLog();
150
151        if (!basedir.exists()) {
152            throw new MojoExecutionException("Can't find project directory " + basedir);
153        }
154
155        if (!sourceDirectory.exists()) {
156            throw new MojoExecutionException("Can't find source directory " + sourceDirectory);
157        } else {
158            log.info("Found: " + sourceDirectory.getAbsolutePath());
159        }
160
161        if (resourcesDirectory != null) {
162            if (!resourcesDirectory.exists()) {
163                log.warn("Can't find resources directory " + resourcesDirectory);
164            } else {
165                log.info("Found: " + resourcesDirectory.getAbsolutePath());
166            }
167        } else {
168            log.warn("No resources directory specified.");
169        }
170
171        createTargetDirectoryIfNotExists();
172
173        MvnWatcher runner = null;
174
175        try {
176
177            if (tasks == null)
178                tasks = getDefaultTasks(basedir.toPath());
179
180            List<Path> directoriesToWatch = new ArrayList<>();
181            directoriesToWatch.add(sourceDirectory.toPath());
182            directoriesToWatch.add(resourcesDirectory.toPath());
183
184            runner = new MvnWatcher(directoriesToWatch, basedir.toPath(), directory.toPath(), tasks);
185            runner.startUpWatcher();
186            runner.terminate = terminate;
187        } catch (IOException e) {
188            e.printStackTrace();
189        }
190
191        if (runner != null)
192            runner.waitForCancel();
193
194    }
195}