Exclude Devtools by default and provide an option to include it
This commit is contained in:
		
							parent
							
								
									d015714cba
								
							
						
					
					
						commit
						6e7e42459b
					
				|  | @ -99,4 +99,22 @@ public interface BootArchive extends Task { | ||||||
| 	 */ | 	 */ | ||||||
| 	void classpath(Object... classpath); | 	void classpath(Object... classpath); | ||||||
| 
 | 
 | ||||||
|  | 	/** | ||||||
|  | 	 * Returns {@code true} if the Devtools jar should be excluded, otherwise | ||||||
|  | 	 * {@code false}. | ||||||
|  | 	 * | ||||||
|  | 	 * @return {@code true} if the Devtools jar should be excluded, or {@code false} if | ||||||
|  | 	 * not | ||||||
|  | 	 */ | ||||||
|  | 	@Input | ||||||
|  | 	boolean isExcludeDevtools(); | ||||||
|  | 
 | ||||||
|  | 	/** | ||||||
|  | 	 * Sets whether or not the Devtools jar should be excluded. | ||||||
|  | 	 * | ||||||
|  | 	 * @param excludeDevtools {@code true} if the Devtools jar should be excluded, or | ||||||
|  | 	 * {@code false} if not | ||||||
|  | 	 */ | ||||||
|  | 	void setExcludeDevtools(boolean excludeDevtools); | ||||||
|  | 
 | ||||||
| } | } | ||||||
|  |  | ||||||
|  | @ -45,13 +45,18 @@ class BootArchiveSupport { | ||||||
| 
 | 
 | ||||||
| 	private final Set<String> storedPathPrefixes; | 	private final Set<String> storedPathPrefixes; | ||||||
| 
 | 
 | ||||||
|  | 	private final PatternSet exclusions = new PatternSet(); | ||||||
|  | 
 | ||||||
| 	private String loaderMainClass; | 	private String loaderMainClass; | ||||||
| 
 | 
 | ||||||
| 	private LaunchScriptConfiguration launchScript = new LaunchScriptConfiguration(); | 	private LaunchScriptConfiguration launchScript = new LaunchScriptConfiguration(); | ||||||
| 
 | 
 | ||||||
|  | 	private boolean excludeDevtools = true; | ||||||
|  | 
 | ||||||
| 	BootArchiveSupport(String... storedPathPrefixes) { | 	BootArchiveSupport(String... storedPathPrefixes) { | ||||||
| 		this.storedPathPrefixes = new HashSet<>(Arrays.asList(storedPathPrefixes)); | 		this.storedPathPrefixes = new HashSet<>(Arrays.asList(storedPathPrefixes)); | ||||||
| 		this.requiresUnpack.include(Specs.satisfyNone()); | 		this.requiresUnpack.include(Specs.satisfyNone()); | ||||||
|  | 		configureExclusions(); | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	void configureManifest(Jar jar, String mainClass) { | 	void configureManifest(Jar jar, String mainClass) { | ||||||
|  | @ -62,18 +67,15 @@ class BootArchiveSupport { | ||||||
| 
 | 
 | ||||||
| 	CopyAction createCopyAction(Jar jar) { | 	CopyAction createCopyAction(Jar jar) { | ||||||
| 		CopyAction copyAction = new BootZipCopyAction(jar.getArchivePath(), | 		CopyAction copyAction = new BootZipCopyAction(jar.getArchivePath(), | ||||||
| 				jar.isPreserveFileTimestamps(), this::requiresUnpacking, | 				jar.isPreserveFileTimestamps(), this.requiresUnpack.getAsSpec(), | ||||||
| 				this.launchScript, this.storedPathPrefixes); | 				this.exclusions.getAsExcludeSpec(), this.launchScript, | ||||||
|  | 				this.storedPathPrefixes); | ||||||
| 		if (!jar.isReproducibleFileOrder()) { | 		if (!jar.isReproducibleFileOrder()) { | ||||||
| 			return copyAction; | 			return copyAction; | ||||||
| 		} | 		} | ||||||
| 		return new ReproducibleOrderingCopyAction(copyAction); | 		return new ReproducibleOrderingCopyAction(copyAction); | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	private boolean requiresUnpacking(FileTreeElement fileTreeElement) { |  | ||||||
| 		return this.requiresUnpack.getAsSpec().isSatisfiedBy(fileTreeElement); |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	String getLoaderMainClass() { | 	String getLoaderMainClass() { | ||||||
| 		return this.loaderMainClass; | 		return this.loaderMainClass; | ||||||
| 	} | 	} | ||||||
|  | @ -98,6 +100,23 @@ class BootArchiveSupport { | ||||||
| 		this.requiresUnpack.include(spec); | 		this.requiresUnpack.include(spec); | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
|  | 	boolean isExcludeDevtools() { | ||||||
|  | 		return this.excludeDevtools; | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	void setExcludeDevtools(boolean excludeDevtools) { | ||||||
|  | 		this.excludeDevtools = excludeDevtools; | ||||||
|  | 		configureExclusions(); | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	private void configureExclusions() { | ||||||
|  | 		Set<String> excludes = new HashSet<String>(); | ||||||
|  | 		if (this.excludeDevtools) { | ||||||
|  | 			excludes.add("**/spring-boot-devtools-*.jar"); | ||||||
|  | 		} | ||||||
|  | 		this.exclusions.setExcludes(excludes); | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
| 	private static final class ReproducibleOrderingCopyAction implements CopyAction { | 	private static final class ReproducibleOrderingCopyAction implements CopyAction { | ||||||
| 
 | 
 | ||||||
| 		private final CopyAction delegate; | 		private final CopyAction delegate; | ||||||
|  |  | ||||||
|  | @ -112,4 +112,14 @@ public class BootJar extends Jar implements BootArchive { | ||||||
| 				classpath); | 				classpath); | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
|  | 	@Override | ||||||
|  | 	public boolean isExcludeDevtools() { | ||||||
|  | 		return this.support.isExcludeDevtools(); | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	@Override | ||||||
|  | 	public void setExcludeDevtools(boolean excludeDevtools) { | ||||||
|  | 		this.support.setExcludeDevtools(excludeDevtools); | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
| } | } | ||||||
|  |  | ||||||
|  | @ -112,4 +112,14 @@ public class BootWar extends War implements BootArchive { | ||||||
| 				classpath); | 				classpath); | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
|  | 	@Override | ||||||
|  | 	public boolean isExcludeDevtools() { | ||||||
|  | 		return this.support.isExcludeDevtools(); | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	@Override | ||||||
|  | 	public void setExcludeDevtools(boolean excludeDevtools) { | ||||||
|  | 		this.support.setExcludeDevtools(excludeDevtools); | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
| } | } | ||||||
|  |  | ||||||
|  | @ -55,16 +55,19 @@ class BootZipCopyAction implements CopyAction { | ||||||
| 
 | 
 | ||||||
| 	private final Spec<FileTreeElement> requiresUnpack; | 	private final Spec<FileTreeElement> requiresUnpack; | ||||||
| 
 | 
 | ||||||
|  | 	private final Spec<FileTreeElement> exclusions; | ||||||
|  | 
 | ||||||
| 	private final LaunchScriptConfiguration launchScript; | 	private final LaunchScriptConfiguration launchScript; | ||||||
| 
 | 
 | ||||||
| 	private final Set<String> storedPathPrefixes; | 	private final Set<String> storedPathPrefixes; | ||||||
| 
 | 
 | ||||||
| 	BootZipCopyAction(File output, boolean preserveFileTimestamps, | 	BootZipCopyAction(File output, boolean preserveFileTimestamps, | ||||||
| 			Spec<FileTreeElement> requiresUnpack, LaunchScriptConfiguration launchScript, | 			Spec<FileTreeElement> requiresUnpack, Spec<FileTreeElement> exclusions, | ||||||
| 			Set<String> storedPathPrefixes) { | 			LaunchScriptConfiguration launchScript, Set<String> storedPathPrefixes) { | ||||||
| 		this.output = output; | 		this.output = output; | ||||||
| 		this.preserveFileTimestamps = preserveFileTimestamps; | 		this.preserveFileTimestamps = preserveFileTimestamps; | ||||||
| 		this.requiresUnpack = requiresUnpack; | 		this.requiresUnpack = requiresUnpack; | ||||||
|  | 		this.exclusions = exclusions; | ||||||
| 		this.launchScript = launchScript; | 		this.launchScript = launchScript; | ||||||
| 		this.storedPathPrefixes = storedPathPrefixes; | 		this.storedPathPrefixes = storedPathPrefixes; | ||||||
| 	} | 	} | ||||||
|  | @ -83,7 +86,7 @@ class BootZipCopyAction implements CopyAction { | ||||||
| 		} | 		} | ||||||
| 		try { | 		try { | ||||||
| 			stream.process(new ZipStreamAction(zipStream, this.output, | 			stream.process(new ZipStreamAction(zipStream, this.output, | ||||||
| 					this.preserveFileTimestamps, this.requiresUnpack, | 					this.preserveFileTimestamps, this.requiresUnpack, this.exclusions, | ||||||
| 					this.storedPathPrefixes)); | 					this.storedPathPrefixes)); | ||||||
| 		} | 		} | ||||||
| 		finally { | 		finally { | ||||||
|  | @ -148,20 +151,26 @@ class BootZipCopyAction implements CopyAction { | ||||||
| 
 | 
 | ||||||
| 		private final Spec<FileTreeElement> requiresUnpack; | 		private final Spec<FileTreeElement> requiresUnpack; | ||||||
| 
 | 
 | ||||||
|  | 		private final Spec<FileTreeElement> exclusions; | ||||||
|  | 
 | ||||||
| 		private final Set<String> storedPathPrefixes; | 		private final Set<String> storedPathPrefixes; | ||||||
| 
 | 
 | ||||||
| 		private ZipStreamAction(ZipOutputStream zipStream, File output, | 		private ZipStreamAction(ZipOutputStream zipStream, File output, | ||||||
| 				boolean preserveFileTimestamps, Spec<FileTreeElement> requiresUnpack, | 				boolean preserveFileTimestamps, Spec<FileTreeElement> requiresUnpack, | ||||||
| 				Set<String> storedPathPrefixes) { | 				Spec<FileTreeElement> exclusions, Set<String> storedPathPrefixes) { | ||||||
| 			this.zipStream = zipStream; | 			this.zipStream = zipStream; | ||||||
| 			this.output = output; | 			this.output = output; | ||||||
| 			this.preserveFileTimestamps = preserveFileTimestamps; | 			this.preserveFileTimestamps = preserveFileTimestamps; | ||||||
| 			this.requiresUnpack = requiresUnpack; | 			this.requiresUnpack = requiresUnpack; | ||||||
|  | 			this.exclusions = exclusions; | ||||||
| 			this.storedPathPrefixes = storedPathPrefixes; | 			this.storedPathPrefixes = storedPathPrefixes; | ||||||
| 		} | 		} | ||||||
| 
 | 
 | ||||||
| 		@Override | 		@Override | ||||||
| 		public void processFile(FileCopyDetailsInternal details) { | 		public void processFile(FileCopyDetailsInternal details) { | ||||||
|  | 			if (this.exclusions.isSatisfiedBy(details)) { | ||||||
|  | 				return; | ||||||
|  | 			} | ||||||
| 			try { | 			try { | ||||||
| 				if (details.isDirectory()) { | 				if (details.isDirectory()) { | ||||||
| 					createDirectory(details); | 					createDirectory(details); | ||||||
|  |  | ||||||
|  | @ -262,6 +262,31 @@ public abstract class AbstractBootArchiveTests<T extends Jar & BootArchive> { | ||||||
| 		assertThat(textFiles).containsExactly("alpha.txt", "bravo.txt", "charlie.txt"); | 		assertThat(textFiles).containsExactly("alpha.txt", "bravo.txt", "charlie.txt"); | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
|  | 	@Test | ||||||
|  | 	public void devtoolsJarIsExcludedByDefault() throws IOException { | ||||||
|  | 		this.task.setMainClass("com.example.Main"); | ||||||
|  | 		this.task.classpath(this.temp.newFile("spring-boot-devtools-0.1.2.jar")); | ||||||
|  | 		this.task.execute(); | ||||||
|  | 		assertThat(this.task.getArchivePath().exists()); | ||||||
|  | 		try (JarFile jarFile = new JarFile(this.task.getArchivePath())) { | ||||||
|  | 			assertThat(jarFile.getEntry(this.libPath + "/spring-boot-devtools-0.1.2.jar")) | ||||||
|  | 					.isNull(); | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	@Test | ||||||
|  | 	public void devtoolsJarCanBeIncluded() throws IOException { | ||||||
|  | 		this.task.setMainClass("com.example.Main"); | ||||||
|  | 		this.task.classpath(this.temp.newFile("spring-boot-devtools-0.1.2.jar")); | ||||||
|  | 		this.task.setExcludeDevtools(false); | ||||||
|  | 		this.task.execute(); | ||||||
|  | 		assertThat(this.task.getArchivePath().exists()); | ||||||
|  | 		try (JarFile jarFile = new JarFile(this.task.getArchivePath())) { | ||||||
|  | 			assertThat(jarFile.getEntry(this.libPath + "/spring-boot-devtools-0.1.2.jar")) | ||||||
|  | 					.isNotNull(); | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
| 	private T configure(T task) throws IOException { | 	private T configure(T task) throws IOException { | ||||||
| 		AbstractArchiveTask archiveTask = task; | 		AbstractArchiveTask archiveTask = task; | ||||||
| 		archiveTask.setBaseName("test"); | 		archiveTask.setBaseName("test"); | ||||||
|  |  | ||||||
|  | @ -47,4 +47,33 @@ public class BootWarTests extends AbstractBootArchiveTests<BootWar> { | ||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
|  | 	@Test | ||||||
|  | 	public void devtoolsJarIsExcludedByDefaultWhenItsOnTheProvidedClasspath() | ||||||
|  | 			throws IOException { | ||||||
|  | 		getTask().setMainClass("com.example.Main"); | ||||||
|  | 		getTask().providedClasspath(this.temp.newFile("spring-boot-devtools-0.1.2.jar")); | ||||||
|  | 		getTask().execute(); | ||||||
|  | 		assertThat(getTask().getArchivePath().exists()); | ||||||
|  | 		try (JarFile jarFile = new JarFile(getTask().getArchivePath())) { | ||||||
|  | 			assertThat(jarFile | ||||||
|  | 					.getEntry("WEB-INF/lib-provided/spring-boot-devtools-0.1.2.jar")) | ||||||
|  | 							.isNull(); | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	@Test | ||||||
|  | 	public void devtoolsJarCanBeIncludedWhenItsOnTheProvidedClasspath() | ||||||
|  | 			throws IOException { | ||||||
|  | 		getTask().setMainClass("com.example.Main"); | ||||||
|  | 		getTask().providedClasspath(this.temp.newFile("spring-boot-devtools-0.1.2.jar")); | ||||||
|  | 		getTask().setExcludeDevtools(false); | ||||||
|  | 		getTask().execute(); | ||||||
|  | 		assertThat(getTask().getArchivePath().exists()); | ||||||
|  | 		try (JarFile jarFile = new JarFile(getTask().getArchivePath())) { | ||||||
|  | 			assertThat(jarFile | ||||||
|  | 					.getEntry("WEB-INF/lib-provided/spring-boot-devtools-0.1.2.jar")) | ||||||
|  | 							.isNotNull(); | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
| } | } | ||||||
|  |  | ||||||
		Loading…
	
		Reference in New Issue