15
15
// specific language governing permissions and limitations
16
16
// under the License.
17
17
18
- package org .openqa .selenium .tools ;
18
+ package org .openqa .selenium .tools . maven ;
19
19
20
20
import com .google .common .base .Splitter ;
21
21
import com .google .common .collect .ImmutableList ;
22
- import com .google .common .hash .HashCode ;
23
22
import com .google .common .hash .Hashing ;
24
23
import com .google .common .io .ByteStreams ;
25
24
import org .openqa .selenium .os .CommandLine ;
52
51
public class MavenPublisher {
53
52
54
53
private static final Logger LOG = Logger .getLogger (MavenPublisher .class .getName ());
55
- private static final ExecutorService EXECUTOR = Executors .newSingleThreadExecutor ( );
54
+ private static final ExecutorService EXECUTOR = Executors .newFixedThreadPool ( 1 );
56
55
57
56
public static void main (String [] args ) throws IOException , InterruptedException , ExecutionException , TimeoutException {
58
57
String repo = args [0 ];
@@ -73,12 +72,14 @@ public static void main(String[] args) throws IOException, InterruptedException,
73
72
Path pom = Paths .get (args [5 ]);
74
73
Path binJar = Paths .get (args [6 ]);
75
74
Path srcJar = Paths .get (args [7 ]);
75
+ Path docJar = Paths .get (args [8 ]);
76
76
77
77
try {
78
78
CompletableFuture <Void > all = CompletableFuture .allOf (
79
79
upload (repo , credentials , coords , ".pom" , pom ),
80
80
upload (repo , credentials , coords , ".jar" , binJar ),
81
- upload (repo , credentials , coords , "-sources.jar" , srcJar )
81
+ upload (repo , credentials , coords , "-sources.jar" , srcJar ),
82
+ upload (repo , credentials , coords , "-javadoc.jar" , docJar )
82
83
);
83
84
all .get (30 , MINUTES );
84
85
} finally {
@@ -102,38 +103,33 @@ private static CompletableFuture<Void> upload(
102
103
coords .artifactId ,
103
104
coords .version );
104
105
105
- // Assume we can hold the thing we're uploading in memory as it makes life a lot easier
106
- byte [] bytes = Files .readAllBytes (item );
107
- HashCode md5 = Hashing .md5 ().hashBytes (bytes );
108
- HashCode sha1 = Hashing .sha1 ().hashBytes (bytes );
106
+ byte [] toHash = Files .readAllBytes (item );
107
+ Path md5 = Files .createTempFile (item .getFileName ().toString (), ".md5" );
108
+ Files .write (md5 , Hashing .md5 ().hashBytes (toHash ).toString ().getBytes (UTF_8 ));
109
+
110
+ Path sha1 = Files .createTempFile (item .getFileName ().toString (), ".sha1" );
111
+ Files .write (sha1 , Hashing .sha1 ().hashBytes (toHash ).toString ().getBytes (UTF_8 ));
109
112
110
113
List <CompletableFuture <?>> uploads = new ArrayList <>();
111
- uploads .add (upload (String .format ("%s%s" , base , append ), credentials , bytes ));
112
- uploads .add (upload (String .format ("%s%s.md5" , base , append ), credentials , md5 . toString (). getBytes ( UTF_8 ) ));
113
- uploads .add (upload (String .format ("%s%s.sha1" , base , append ), credentials , sha1 . toString (). getBytes ( UTF_8 ) ));
114
+ uploads .add (upload (String .format ("%s%s" , base , append ), credentials , item ));
115
+ uploads .add (upload (String .format ("%s%s.md5" , base , append ), credentials , md5 ));
116
+ uploads .add (upload (String .format ("%s%s.sha1" , base , append ), credentials , sha1 ));
114
117
115
118
if (credentials .getGpgSign ()) {
116
- String filename = String .format ("%s-%s%s" , coords .artifactId , coords .version , append );
117
-
118
- byte [] bytesSignature = sign (credentials , filename , Files .readAllBytes (item ));
119
- uploads .add (upload (String .format ("%s%s.asc" , base , append ), credentials , bytesSignature ));
120
-
121
- byte [] md5Signature = sign (credentials , filename + ".md5" , md5 .toString ().getBytes (UTF_8 ));
122
- uploads .add (upload (String .format ("%s%s.md5.asc" , base , append ), credentials , md5Signature ));
123
-
124
- byte [] sha1Signature = sign (credentials , filename + ".sha1" , sha1 .toString ().getBytes (UTF_8 ));
125
- uploads .add (upload (String .format ("%s%s.sha1.asc" , base , append ), credentials , sha1Signature ));
119
+ uploads .add (upload (String .format ("%s%s.asc" , base , append ), credentials , sign (item )));
120
+ uploads .add (upload (String .format ("%s%s.md5.asc" , base , append ), credentials , sign (md5 )));
121
+ uploads .add (upload (String .format ("%s%s.sha1.asc" , base , append ), credentials , sign (sha1 )));
126
122
}
127
123
128
124
return CompletableFuture .allOf (uploads .toArray (new CompletableFuture <?>[0 ]));
129
125
}
130
126
131
- private static CompletableFuture <Void > upload (String targetUrl , Credentials credentials , byte [] contents ) {
127
+ private static CompletableFuture <Void > upload (String targetUrl , Credentials credentials , Path toUpload ) {
132
128
Callable <Void > callable ;
133
129
if (targetUrl .startsWith ("http://" ) || targetUrl .startsWith ("https://" )) {
134
- callable = httpUpload (targetUrl , credentials , contents );
130
+ callable = httpUpload (targetUrl , credentials , toUpload );
135
131
} else {
136
- callable = writeFile (targetUrl , contents );
132
+ callable = writeFile (targetUrl , toUpload );
137
133
}
138
134
139
135
CompletableFuture <Void > toReturn = new CompletableFuture <>();
@@ -148,8 +144,9 @@ private static CompletableFuture<Void> upload(String targetUrl, Credentials cred
148
144
return toReturn ;
149
145
}
150
146
151
- private static Callable <Void > httpUpload (String targetUrl , Credentials credentials , byte [] contents ) {
147
+ private static Callable <Void > httpUpload (String targetUrl , Credentials credentials , Path toUpload ) {
152
148
return () -> {
149
+ LOG .info (String .format ("Uploading to %s" , targetUrl ));
153
150
URL url = new URL (targetUrl );
154
151
155
152
HttpURLConnection connection = (HttpURLConnection ) url .openConnection ();
@@ -160,10 +157,12 @@ private static Callable<Void> httpUpload(String targetUrl, Credentials credentia
160
157
String .format ("%s:%s" , credentials .getUser (), credentials .getPassword ()).getBytes (US_ASCII ));
161
158
connection .setRequestProperty ("Authorization" , "BASIC " + basicAuth );
162
159
}
163
- connection .setRequestProperty ("Content-Length" , "" + contents . length );
160
+ connection .setRequestProperty ("Content-Length" , "" + Files . size ( toUpload ) );
164
161
165
162
try (OutputStream out = connection .getOutputStream ()) {
166
- out .write (contents );
163
+ try (InputStream is = Files .newInputStream (toUpload )) {
164
+ is .transferTo (out );
165
+ }
167
166
168
167
int code = connection .getResponseCode ();
169
168
@@ -178,22 +177,26 @@ private static Callable<Void> httpUpload(String targetUrl, Credentials credentia
178
177
}
179
178
}
180
179
}
180
+ LOG .info (String .format ("Upload to %s complete." , targetUrl ));
181
181
return null ;
182
182
};
183
183
}
184
184
185
- private static Callable <Void > writeFile (String targetUrl , byte [] contents ) {
185
+ private static Callable <Void > writeFile (String targetUrl , Path toUpload ) {
186
186
return () -> {
187
+ LOG .info (String .format ("Copying %s to %s" , toUpload , targetUrl ));
187
188
Path path = Paths .get (new URL (targetUrl ).toURI ());
188
189
Files .createDirectories (path .getParent ());
189
190
Files .deleteIfExists (path );
190
- Files .write ( path , contents );
191
+ Files .copy ( toUpload , path );
191
192
192
193
return null ;
193
194
};
194
195
}
195
196
196
- private static byte [] sign (Credentials credentials , String fileName , byte [] data ) throws IOException {
197
+ private static Path sign (Path toSign ) throws IOException {
198
+ LOG .info ("Signing " + toSign );
199
+
197
200
// Ideally, we'd use BouncyCastle for this, but for now brute force by assuming
198
201
// the gpg binary is on the path
199
202
@@ -203,21 +206,28 @@ private static byte[] sign(Credentials credentials, String fileName, byte[] data
203
206
}
204
207
205
208
Path dir = Files .createTempDirectory ("maven-sign" );
206
- Path file = dir .resolve (fileName + ".asc" );
209
+ Path file = dir .resolve (toSign . getFileName () + ".asc" );
207
210
208
211
List <String > args = ImmutableList .of (
209
- "gpg" , "-ab " , "--batch " ,
210
- "-o" , file .toAbsolutePath ().toString ());
212
+ "gpg" , "--use-agent " , "--armor" , "--detach-sign" , "--no-tty " ,
213
+ "-o" , file .toAbsolutePath ().toString (), toSign . toAbsolutePath (). toString () );
211
214
212
215
CommandLine gpg = new CommandLine (args .toArray (new String [0 ]));
213
216
gpg .execute ();
214
217
if (!gpg .isSuccessful ()) {
215
- throw new IllegalStateException ("Unable to sign: " + fileName + "\n " + gpg .getStdOut ());
218
+ throw new IllegalStateException ("Unable to sign: " + toSign + "\n " + gpg .getStdOut ());
219
+ }
220
+
221
+ // Verify the signature
222
+ CommandLine verify = new CommandLine (
223
+ "gpg" , "--verify" , "--verbose" , "--verbose" ,
224
+ file .toAbsolutePath ().toString (), toSign .toAbsolutePath ().toString ());
225
+ verify .execute ();
226
+ if (!verify .isSuccessful ()) {
227
+ throw new IllegalStateException ("Unable to verify signature of " + toSign + "\n " + gpg .getStdOut ());
216
228
}
217
229
218
- byte [] bytes = Files .readAllBytes (file );
219
- Files .delete (file );
220
- return bytes ;
230
+ return file ;
221
231
}
222
232
223
233
private static class Coordinates {
0 commit comments