Skip to content

Commit af8a061

Browse files
committed
Move the creation of dynamic task in the afterEvaluate() listener for
compatibility with Gradle 5 and Gradle 6. #85
1 parent 7e7bb32 commit af8a061

File tree

5 files changed

+169
-20
lines changed

5 files changed

+169
-20
lines changed

src/com/inet/gradle/setup/dmg/Dmg.java

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,8 @@
2828
import com.inet.gradle.setup.SetupBuilder;
2929
import com.inet.gradle.setup.abstracts.AbstractUnixSetupTask;
3030
import com.inet.gradle.setup.abstracts.LocalizedResource;
31+
import com.inet.gradle.setup.abstracts.Service;
32+
import com.inet.gradle.setup.util.GradleUtils;
3133

3234
import groovy.lang.Closure;
3335

@@ -54,6 +56,8 @@ public class Dmg extends AbstractUnixSetupTask {
5456

5557
private List<PreferencesLink> preferencesLink = new ArrayList<>();
5658

59+
final List<OSXApplicationBuilder> appBuilders = new ArrayList<>();
60+
5761
private List<String> jreIncludes = Arrays.asList( new String[] {
5862
"bin/java",
5963
"lib/",
@@ -80,6 +84,19 @@ public class Dmg extends AbstractUnixSetupTask {
8084
*/
8185
public Dmg() {
8286
super( "dmg" );
87+
getProject().afterEvaluate( (project) -> {
88+
// if the "dmg" task should be executed then create some possible extra tasks on the end of the configuration phase
89+
boolean isExecute = GradleUtils.isTaskExecute( Dmg.this, project );
90+
if( isExecute ) {
91+
SetupBuilder setup = getSetupBuilder();
92+
for( Service service : setup.getServices() ) {
93+
ProjectInternal projInternal = (ProjectInternal)project;
94+
OSXApplicationBuilder builder = new OSXApplicationBuilder( Dmg.this, setup, projInternal.getFileResolver() );
95+
builder.configSubTasks( service );
96+
appBuilders.add( builder );
97+
}
98+
}
99+
});
83100
}
84101

85102
/**

src/com/inet/gradle/setup/dmg/DmgBuilder.java

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -83,10 +83,10 @@ public void build() throws RuntimeException {
8383
}
8484

8585
// Build all services
86-
for( Service service : setup.getServices() ) {
87-
new OSXApplicationBuilder( task, setup, fileResolver ).buildService( service );
86+
for( OSXApplicationBuilder builder : task.appBuilders ) {
87+
builder.buildService();
8888
if ( firstExecutableName == null ) {
89-
firstExecutableName = service.getDisplayName();
89+
firstExecutableName = builder.getService().getDisplayName();
9090
}
9191
}
9292

src/com/inet/gradle/setup/dmg/OSXApplicationBuilder.java

Lines changed: 25 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,10 @@
1616
*/
1717
public class OSXApplicationBuilder extends AbstractOSXApplicationBuilder<Dmg, SetupBuilder> {
1818

19+
private Service service;
20+
21+
private OSXPrefPaneCreator prefPaneCreator;
22+
1923
/**
2024
* Setup this builder.
2125
*
@@ -27,14 +31,32 @@ protected OSXApplicationBuilder( Dmg task, SetupBuilder setup, FileResolver file
2731
super( task, setup, fileResolver );
2832
}
2933

34+
/**
35+
* Create sub tasks for a service,this must be called in project.afterEvaluate().
36+
*
37+
* @param service the service
38+
*/
39+
void configSubTasks( Service service ) {
40+
this.service = service;
41+
this.prefPaneCreator = new OSXPrefPaneCreator( task, getSetupBuilder(), fileResolver, service );
42+
}
43+
44+
/**
45+
* Get the service for which this builder was created or null if it only an application.
46+
*
47+
* @return the service
48+
*/
49+
Service getService() {
50+
return service;
51+
}
52+
3053
/**
3154
* Create Application from service provided. Also create the preference panel
3255
* and put it into the application. Will also create the installer wrapper package of this application
3356
*
34-
* @param service the service
3557
* @throws Throwable error.
3658
*/
37-
void buildService( Service service ) throws Throwable {
59+
void buildService() throws Throwable {
3860

3961
// We need the executable. It has a different meaning than on other systems.
4062
if( service.getExecutable() == null || service.getExecutable().isEmpty() ) {
@@ -45,7 +67,7 @@ void buildService( Service service ) throws Throwable {
4567
prepareApplication( service, false );
4668
finishApplication();
4769
copyBundleFiles( service );
48-
new OSXPrefPaneCreator( task, getSetupBuilder(), fileResolver ).create( service );
70+
prefPaneCreator.create();
4971

5072
// codesigning will be done on the final package.
5173
// codeSignApplication( service );

src/com/inet/gradle/setup/dmg/OSXPrefPaneCreator.java

Lines changed: 34 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
import java.util.Arrays;
99
import java.util.HashMap;
1010

11+
import org.gradle.api.DefaultTask;
1112
import org.gradle.api.GradleException;
1213
import org.gradle.api.Project;
1314
import org.gradle.api.artifacts.Configuration;
@@ -27,10 +28,40 @@ public class OSXPrefPaneCreator extends AbstractOSXApplicationBuilder<Dmg, Setup
2728

2829
private Project project;
2930

30-
protected OSXPrefPaneCreator( Dmg task, SetupBuilder setup, FileResolver fileResolver ) {
31+
private Service service;
32+
33+
private String displayName;
34+
35+
private String internalName;
36+
37+
private File prefPaneSource;
38+
39+
protected OSXPrefPaneCreator( Dmg task, SetupBuilder setup, FileResolver fileResolver, Service service ) {
3140
super( task, setup, fileResolver );
3241
buildDir = task.getTemporaryDir();
3342
project = task.getProject();
43+
this.service = service;
44+
45+
displayName = service.getDisplayName();
46+
internalName = displayName.replaceAll( "[^A-Za-z0-9]", "" );
47+
48+
// Create a task and run it before, this must be called in project.afterEvaluate()
49+
GradleBuild gradleBuild = project.getTasks().create("OSXPrefPaneBuildTask-"+internalName, GradleBuild.class);
50+
gradleBuild.setDescription( "Run the xcodebuild task for the prefpane." );
51+
gradleBuild.setTasks( Arrays.asList( "clean", "xcodebuild" ) );
52+
task.dependsOn( gradleBuild );
53+
54+
DefaultTask gradleBuildInit = project.getTasks().create("OSXPrefPaneBuildTask-Init-"+internalName, DefaultTask.class);
55+
gradleBuildInit.doFirst( (t) -> {
56+
try {
57+
prefPaneSource = unpackAndPatchPrefPaneSource( internalName );
58+
} catch( Exception ex ) {
59+
ex.printStackTrace();
60+
throw new RuntimeException( ex );
61+
}
62+
gradleBuild.setBuildFile( new File( prefPaneSource, "build.gradle" ) );
63+
} );
64+
gradleBuild.dependsOn( gradleBuildInit );
3465
}
3566

3667
/**
@@ -42,18 +73,7 @@ protected OSXPrefPaneCreator( Dmg task, SetupBuilder setup, FileResolver fileRes
4273
* @return the file to the created pref pane.
4374
* @throws Exception if any error occur
4475
*/
45-
void create( Service service ) throws Exception {
46-
47-
String displayName = service.getDisplayName();
48-
String internalName = displayName.replaceAll( "[^A-Za-z0-9]", "" );
49-
File prefPaneSource = unpackAndPatchPrefPaneSource( internalName );
50-
51-
GradleBuild gradleBuild = project.getTasks().create("OSXPrefPaneBuildTask", GradleBuild.class);
52-
gradleBuild.setDescription( "Run the xcodebuild task for the prefpane." );
53-
gradleBuild.setBuildFile( new File( prefPaneSource, "build.gradle" ) );
54-
gradleBuild.setTasks( Arrays.asList( "clean", "xcodebuild" ) );
55-
gradleBuild.execute();
56-
76+
void create() throws Exception {
5777
File prefPaneBinary = new File( prefPaneSource, "build/sym/Release/" + internalName + ".prefPane" );
5878

5979
if( !prefPaneBinary.exists() ) {
@@ -169,7 +189,7 @@ private File unpackAndPatchPrefPaneSource( String internalName ) throws Exceptio
169189
}
170190

171191
// Prepare output directory
172-
File outputDir = new File( buildDir, configName );
192+
File outputDir = new File( buildDir, internalName );
173193
outputDir.mkdirs();
174194

175195
URL dirURL = OSXPrefPaneCreator.class.getClassLoader().getResource( "com/inet/gradle/setup/dmg/preferences/build.gradle" );
Lines changed: 90 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,90 @@
1+
/*
2+
* Copyright 2019 i-net software
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
package com.inet.gradle.setup.util;
17+
18+
import java.util.List;
19+
import java.util.Objects;
20+
import java.util.Set;
21+
22+
import org.gradle.api.Project;
23+
import org.gradle.api.Task;
24+
import org.gradle.api.tasks.TaskContainer;
25+
26+
public abstract class GradleUtils {
27+
28+
/**
29+
* Checked if the given task will be executed because set in command line or depends on other executed task.
30+
*
31+
* @param task the task to check
32+
* @param project the current project
33+
* @return true, if the task will be executed
34+
*/
35+
public static boolean isTaskExecute( Task task, Project project ) {
36+
String name = task.getName();
37+
List<String> startTasks = project.getGradle().getStartParameter().getTaskNames();
38+
TaskContainer tasks = project.getTasks();
39+
for( String startTaskName : startTasks ) {
40+
if( Objects.equals( name, startTaskName ) ) {
41+
// direct call of the task in the command line
42+
return true;
43+
}
44+
try {
45+
Task startTask = tasks.getByName( startTaskName );
46+
if( isTaskExecute( task, name, startTask, tasks ) ) {
47+
return true;
48+
}
49+
} catch( Throwable th ) {
50+
// can occur if there is a circle in the dependsOn
51+
}
52+
}
53+
54+
return false;
55+
}
56+
57+
/**
58+
* Checked if the given task will be executed because set in command line or depends on other executed task.
59+
*
60+
* @param task the task to check
61+
* @param name the name to check
62+
* @param startTask a task that will be executed
63+
* @param tasks all tasks
64+
* @return true, if the task will be executed
65+
*/
66+
private static boolean isTaskExecute( Task task, String name, Task startTask, TaskContainer tasks ) {
67+
if( startTask == null ) {
68+
return false;
69+
}
70+
Set<Object> dependsOn = startTask.getDependsOn(); // can contain a task name, a task or other objects
71+
for( Object depObject : dependsOn ) {
72+
if( Objects.equals( name, depObject ) ) {
73+
return true;
74+
}
75+
if( Objects.equals( task, depObject ) ) {
76+
return true;
77+
}
78+
Task depTask = null;
79+
if( depObject instanceof String ) {
80+
depTask = tasks.getByName( (String)depObject );
81+
} else if( depObject instanceof Task ) {
82+
depTask = (Task)depObject;
83+
}
84+
if( isTaskExecute( task, name, depTask, tasks ) ) {
85+
return true;
86+
}
87+
}
88+
return false;
89+
}
90+
}

0 commit comments

Comments
 (0)