26
26
import java .util .Set ;
27
27
import java .util .TreeMap ;
28
28
import java .util .function .Function ;
29
+ import java .util .function .Supplier ;
29
30
31
+ import org .gradle .api .GradleException ;
30
32
import org .gradle .api .file .CopySpec ;
31
33
import org .gradle .api .file .FileCopyDetails ;
32
34
import org .gradle .api .file .FileTreeElement ;
36
38
import org .gradle .api .internal .file .copy .FileCopyDetailsInternal ;
37
39
import org .gradle .api .java .archives .Attributes ;
38
40
import org .gradle .api .java .archives .Manifest ;
41
+ import org .gradle .api .provider .Property ;
39
42
import org .gradle .api .specs .Spec ;
40
43
import org .gradle .api .specs .Specs ;
41
44
import org .gradle .api .tasks .WorkResult ;
42
45
import org .gradle .api .tasks .bundling .Jar ;
43
46
import org .gradle .api .tasks .util .PatternSet ;
47
+ import org .gradle .util .GradleVersion ;
44
48
45
49
/**
46
50
* Support class for implementations of {@link BootArchive}.
@@ -125,8 +129,8 @@ CopyAction createCopyAction(Jar jar, ResolvedDependencies resolvedDependencies,
125
129
File output = jar .getArchiveFile ().get ().getAsFile ();
126
130
Manifest manifest = jar .getManifest ();
127
131
boolean preserveFileTimestamps = jar .isPreserveFileTimestamps ();
128
- Integer dirMode = jar . getDirMode ();
129
- Integer fileMode = jar . getFileMode ();
132
+ Integer dirMode = getDirMode (jar );
133
+ Integer fileMode = getFileMode (jar );
130
134
boolean includeDefaultLoader = isUsingDefaultLoader (jar );
131
135
Spec <FileTreeElement > requiresUnpack = this .requiresUnpack .getAsSpec ();
132
136
Spec <FileTreeElement > exclusions = this .exclusions .getAsExcludeSpec ();
@@ -140,6 +144,46 @@ CopyAction createCopyAction(Jar jar, ResolvedDependencies resolvedDependencies,
140
144
return jar .isReproducibleFileOrder () ? new ReproducibleOrderingCopyAction (action ) : action ;
141
145
}
142
146
147
+ private Integer getDirMode (CopySpec copySpec ) {
148
+ return getMode (copySpec , "getDirPermissions" , copySpec ::getDirMode );
149
+ }
150
+
151
+ private Integer getFileMode (CopySpec copySpec ) {
152
+ return getMode (copySpec , "getFilePermissions" , copySpec ::getFileMode );
153
+ }
154
+
155
+ @ SuppressWarnings ("unchecked" )
156
+ private Integer getMode (CopySpec copySpec , String methodName , Supplier <Integer > fallback ) {
157
+ if (GradleVersion .current ().compareTo (GradleVersion .version ("8.3" )) >= 0 ) {
158
+ try {
159
+ Object filePermissions = ((Property <Object >) copySpec .getClass ().getMethod (methodName ).invoke (copySpec ))
160
+ .getOrNull ();
161
+ return getMode (filePermissions );
162
+ }
163
+ catch (Exception ex ) {
164
+ throw new GradleException ("Failed to get permissions" , ex );
165
+ }
166
+ }
167
+ return fallback .get ();
168
+ }
169
+
170
+ private Integer getMode (Object permissions ) throws Exception {
171
+ if (permissions == null ) {
172
+ return null ;
173
+ }
174
+ String user = asIntegerString (permissions .getClass ().getMethod ("getUser" ).invoke (permissions ));
175
+ String group = asIntegerString (permissions .getClass ().getMethod ("getGroup" ).invoke (permissions ));
176
+ String other = asIntegerString (permissions .getClass ().getMethod ("getOther" ).invoke (permissions ));
177
+ return Integer .parseInt ("0" + user + group + other , 8 );
178
+ }
179
+
180
+ private String asIntegerString (Object permissions ) throws Exception {
181
+ boolean read = (boolean ) permissions .getClass ().getMethod ("getRead" ).invoke (permissions );
182
+ boolean write = (boolean ) permissions .getClass ().getMethod ("getWrite" ).invoke (permissions );
183
+ boolean execute = (boolean ) permissions .getClass ().getMethod ("getExecute" ).invoke (permissions );
184
+ return Integer .toString (((read ) ? 4 : 0 ) + ((write ) ? 2 : 0 ) + ((execute ) ? 1 : 0 ));
185
+ }
186
+
143
187
private boolean isUsingDefaultLoader (Jar jar ) {
144
188
return DEFAULT_LAUNCHER_CLASSES .contains (jar .getManifest ().getAttributes ().get ("Main-Class" ));
145
189
}
0 commit comments