1212import java .io .File ;
1313import java .net .URL ;
1414import java .nio .file .Path ;
15- import java .time .Instant ;
16- import java .time .temporal .ChronoUnit ;
1715import java .util .ArrayList ;
16+ import java .util .Collection ;
1817import java .util .List ;
18+ import java .util .function .Predicate ;
19+ import java .util .stream .Collectors ;
1920import org .gradle .api .Plugin ;
2021import org .gradle .api .Project ;
22+ import org .gradle .api .artifacts .Configuration ;
23+ import org .gradle .api .artifacts .ResolvedArtifact ;
2124import org .gradle .api .file .Directory ;
22- import org .gradle .api .file .FileCollection ;
2325import org .gradle .api .plugins .ApplicationPlugin ;
2426import org .gradle .api .plugins .JavaApplication ;
2527import org .gradle .api .plugins .JavaPluginConvention ;
2628import org .gradle .api .provider .Provider ;
2729import org .gradle .api .resources .TextResource ;
30+ import org .gradle .api .specs .Spec ;
2831import org .gradle .api .tasks .SourceSet ;
2932import org .gradle .api .tasks .SourceSetOutput ;
3033import org .gradle .api .tasks .Sync ;
@@ -37,9 +40,9 @@ public class HypertraceDockerJavaApplicationPlugin implements Plugin<Project> {
3740 public static final String DOCKERFILE_TASK_NAME = "generateJavaApplicationDockerfile" ;
3841 public static final String DOCKER_START_SCRIPT_TASK_NAME = "generateJavaApplicationDockerStartScript" ;
3942 public static final String SYNC_BUILD_CONTEXT_TASK_NAME = "syncJavaApplicationDockerContext" ;
40- private static final String DOCKER_BUILD_CONTEXT_EXTERNAL_LIBS_DIR = "externalLibs" ;
41-
4243 private static final String DOCKER_BUILD_CONTEXT_LOCAL_LIBS_DIR = "localLibs" ;
44+ private static final String DOCKER_BUILD_CONTEXT_ORG_LIBS_DIR = "orgLibs" ;
45+ private static final String DOCKER_BUILD_CONTEXT_EXTERNAL_LIBS_DIR = "externalLibs" ;
4346 private static final String DOCKER_BUILD_CONTEXT_CLASSES_DIR = "classes" ;
4447 private static final String DOCKER_BUILD_CONTEXT_RESOURCES_DIR = "resources" ;
4548 private static final String DOCKER_BUILD_CONTEXT_SCRIPTS_DIR = "scripts" ;
@@ -119,6 +122,9 @@ void createDockerfileTask(Project project, HypertraceDockerJavaApplication javaA
119122 dockerfile .copyFile (provideIfDirectoryExists (dockerfile .getDestDir ()
120123 .map (dir -> dir .dir (DOCKER_BUILD_CONTEXT_EXTERNAL_LIBS_DIR )))
121124 .map (unused -> new CopyFile (DOCKER_BUILD_CONTEXT_EXTERNAL_LIBS_DIR , DOCKER_BUILD_CONTEXT_EXTERNAL_LIBS_DIR )));
125+ dockerfile .copyFile (provideIfDirectoryExists (dockerfile .getDestDir ()
126+ .map (dir -> dir .dir (DOCKER_BUILD_CONTEXT_ORG_LIBS_DIR )))
127+ .map (unused -> new CopyFile (DOCKER_BUILD_CONTEXT_ORG_LIBS_DIR , DOCKER_BUILD_CONTEXT_ORG_LIBS_DIR )));
122128 dockerfile .copyFile (provideIfDirectoryExists (dockerfile .getDestDir ()
123129 .map (dir -> dir .dir (DOCKER_BUILD_CONTEXT_LOCAL_LIBS_DIR )))
124130 .map (unused -> new CopyFile (DOCKER_BUILD_CONTEXT_LOCAL_LIBS_DIR , DOCKER_BUILD_CONTEXT_LOCAL_LIBS_DIR )));
@@ -148,6 +154,7 @@ void createDockerfileTask(Project project, HypertraceDockerJavaApplication javaA
148154 private void createDockerStartScriptTask (Project project ) {
149155 project .getTasks ()
150156 .register (DOCKER_START_SCRIPT_TASK_NAME , CreateStartScripts .class , startScript -> {
157+ startScript .getInputs ().file (this .getStartScriptTemplate (project ));
151158 ((TemplateBasedScriptGenerator ) startScript .getUnixStartScriptGenerator ()).setTemplate (this .getStartScriptTemplate (project ));
152159 startScript .setGroup (DockerPlugin .TASK_GROUP );
153160 startScript .setDescription ("Creates a startup script for use by the docker container" );
@@ -178,22 +185,32 @@ private void createContextSyncTask(Project project) {
178185 .map (Dockerfile ::getDestDir )
179186 .get ());
180187 sync .with (project .copySpec (spec -> {
181- // We split deps into two dirs depending on last modified time, with the assumption that any local jars will be recently built
182- Instant time = Instant .now ()
183- .minus (30 , ChronoUnit .MINUTES );
184- spec .into (DOCKER_BUILD_CONTEXT_LOCAL_LIBS_DIR , childSpec -> childSpec .from (getRuntimeClasspath (project )
185- .filter (file -> Instant .ofEpochMilli (file .lastModified ())
186- .isAfter (time ))));
187- spec .into (DOCKER_BUILD_CONTEXT_EXTERNAL_LIBS_DIR , childSpec -> childSpec .from (getRuntimeClasspath (project )
188- .filter (file -> Instant .ofEpochMilli (file .lastModified ())
189- .isBefore (time ))));
188+ spec .into (DOCKER_BUILD_CONTEXT_LOCAL_LIBS_DIR , childSpec -> childSpec .from (this .buildFilteredLibraryProvider (project , this .buildLocalArtifactPredicate (project ))));
189+ spec .into (DOCKER_BUILD_CONTEXT_ORG_LIBS_DIR , childSpec -> childSpec .from (this .buildFilteredLibraryProvider (project , this .buildLocalArtifactPredicate (project )
190+ .negate ()
191+ .and (this .getOrgLibPredicate (project )))));
192+ spec .into (DOCKER_BUILD_CONTEXT_EXTERNAL_LIBS_DIR , childSpec -> childSpec .from (this .buildFilteredLibraryProvider (project , this .buildLocalArtifactPredicate (project )
193+ .negate ()
194+ .and (this .getOrgLibPredicate (project )
195+ .negate ()))));
190196 spec .into (DOCKER_BUILD_CONTEXT_CLASSES_DIR , childSpec -> childSpec .from (mainSourceSetOutput (project ).getClassesDirs ()));
191197 spec .into (DOCKER_BUILD_CONTEXT_RESOURCES_DIR , childSpec -> childSpec .from (mainSourceSetOutput (project ).getResourcesDir ()));
192198 }));
193199 });
194200 }
195201
196- private FileCollection getRuntimeClasspath (Project project ) {
202+ private Predicate <ResolvedArtifact > buildLocalArtifactPredicate (Project project ) {
203+ // Either matching version or missing version indicating a composite project
204+ return artifact -> {
205+ String artifactVersion = artifact .getModuleVersion ()
206+ .getId ()
207+ .getVersion ();
208+ return artifactVersion .equals (project .getVersion ()
209+ .toString ()) || artifactVersion .equals ("unspecified" );
210+ };
211+ }
212+
213+ private Configuration getRuntimeClasspath (Project project ) {
197214 return project .getConfigurations ()
198215 .getByName (RUNTIME_CLASSPATH_CONFIGURATION_NAME );
199216 }
@@ -218,4 +235,18 @@ private TextResource getStartScriptTemplate(Project project) {
218235 .getText ()
219236 .fromUri (requireNonNull (resourceUrl ));
220237 }
238+
239+ private Provider <Collection <File >> buildFilteredLibraryProvider (Project project , Predicate <ResolvedArtifact > filterPredicate ) {
240+ return project .provider (() -> this .getRuntimeClasspath (project )
241+ .getResolvedConfiguration ()
242+ .getResolvedArtifacts ()
243+ .stream ()
244+ .filter (filterPredicate )
245+ .map (ResolvedArtifact ::getFile )
246+ .collect (Collectors .toSet ()));
247+ }
248+
249+ private Predicate <ResolvedArtifact > getOrgLibPredicate (Project project ) {
250+ return this .getHypertraceDockerApplicationExtension (project ).orgLibrarySpec ::isSatisfiedBy ;
251+ }
221252}
0 commit comments