Commits

Thinkofname authored 3f1a3daee70
Remove git bash requirement
No tags

src/main/java/org/spigotmc/builder/Builder.java

Modified
9 9 import com.google.common.io.ByteStreams;
10 10 import com.google.common.io.CharStreams;
11 11 import com.google.common.io.Files;
12 12 import com.google.common.io.Resources;
13 13 import com.google.gson.Gson;
14 14 import difflib.DiffUtils;
15 15 import difflib.Patch;
16 16 import java.io.BufferedOutputStream;
17 17 import java.io.BufferedReader;
18 18 import java.io.BufferedWriter;
19 +import java.io.ByteArrayInputStream;
19 20 import java.io.File;
20 21 import java.io.FileDescriptor;
21 22 import java.io.FileNotFoundException;
22 23 import java.io.FileOutputStream;
23 24 import java.io.FileWriter;
24 25 import java.io.FilenameFilter;
25 26 import java.io.IOException;
26 27 import java.io.InputStream;
27 28 import java.io.InputStreamReader;
28 29 import java.io.OutputStream;
45 46 import javax.net.ssl.SSLSession;
46 47 import javax.net.ssl.TrustManager;
47 48 import javax.net.ssl.X509TrustManager;
48 49
49 50 import joptsimple.OptionParser;
50 51 import joptsimple.OptionSet;
51 52 import joptsimple.OptionSpec;
52 53 import lombok.RequiredArgsConstructor;
53 54 import org.apache.commons.io.FileUtils;
54 55 import org.apache.commons.io.output.TeeOutputStream;
56 +import org.eclipse.jgit.api.AddCommand;
57 +import org.eclipse.jgit.api.FetchCommand;
55 58 import org.eclipse.jgit.api.Git;
56 59 import org.eclipse.jgit.api.ResetCommand;
57 60 import org.eclipse.jgit.api.errors.GitAPIException;
61 +import org.eclipse.jgit.lib.CoreConfig;
62 +import org.eclipse.jgit.lib.Repository;
63 +import org.eclipse.jgit.lib.StoredConfig;
58 64 import org.eclipse.jgit.revwalk.RevCommit;
65 +import org.eclipse.jgit.transport.RefSpec;
66 +import org.eclipse.jgit.transport.RemoteConfig;
67 +import org.eclipse.jgit.transport.TagOpt;
68 +import org.eclipse.jgit.transport.URIish;
59 69
60 70 public class Builder
61 71 {
62 72
63 73 public static final String LOG_FILE = "BuildTools.log.txt";
64 74 public static final boolean IS_WINDOWS = System.getProperty( "os.name" ).startsWith( "Windows" );
65 75 public static final File CWD = new File( "." );
66 76 private static boolean dontUpdate;
67 77 private static boolean skipCompile;
68 78 private static boolean generateSource;
69 79 private static boolean generateDocs;
70 80 private static boolean dev;
81 + private static boolean bash;
71 82
72 83 public static void main(String[] args) throws Exception
73 84 {
74 85 // May be null
75 86 String buildVersion = Builder.class.getPackage().getImplementationVersion();
76 87 int buildNumber = -1;
77 88 if ( buildVersion != null )
78 89 {
79 90 String[] split = buildVersion.split( "-" );
80 91 if ( split.length == 4 )
90 101 System.out.println( "Loading BuildTools version: " + buildVersion + " (#" + buildNumber + ")" );
91 102
92 103 OptionParser parser = new OptionParser();
93 104 OptionSpec<Void> disableCertFlag = parser.accepts( "disable-certificate-check" );
94 105 OptionSpec<Void> dontUpdateFlag = parser.accepts( "dont-update" );
95 106 OptionSpec<Void> skipCompileFlag = parser.accepts( "skip-compile" );
96 107 OptionSpec<Void> generateSourceFlag = parser.accepts( "generate-source" );
97 108 OptionSpec<Void> generateDocsFlag = parser.accepts( "generate-docs" );
98 109 OptionSpec<Void> devFlag = parser.accepts( "dev" );
99 110 OptionSpec<String> jenkinsVersion = parser.accepts( "rev" ).withRequiredArg().defaultsTo( "latest" );
111 + OptionSpec<Void> bashFlag = parser.accepts( "bash" );
100 112
101 113 OptionSet options = parser.parse( args );
102 114
103 115 if ( options.has( disableCertFlag ) )
104 116 {
105 117 disableHttpsCertificateCheck();
106 118 }
107 119 dontUpdate = options.has( dontUpdateFlag );
108 120 skipCompile = options.has( skipCompileFlag );
109 121 generateSource = options.has( generateSourceFlag );
110 122 generateDocs = options.has( generateDocsFlag );
111 123 dev = options.has( devFlag );
124 + bash = options.has( bashFlag );
112 125
113 126 logOutput();
114 127
115 128 if ( Float.parseFloat( System.getProperty( "java.class.version" ) ) < 51.0 )
116 129 {
117 130 System.err.println( "*** WARNING *** You are not using Java 7 or above. Although this will work, it is highly discouraged due to the security issues present." );
118 131 System.err.println( "*** WARNING *** Use java -version to check your version and update as soon as possible." );
119 132 }
120 133
121 - try
122 - {
123 - runProcess( CWD, "bash", "-c", "exit" );
124 - } catch ( Exception ex )
125 - {
126 - System.out.println( "You must run this jar through bash (msysgit)" );
127 - System.exit( 1 );
128 - }
129 -
130 - try
131 - {
132 - runProcess( CWD, "git", "config", "--global", "user.name" );
133 - } catch ( Exception ex )
134 - {
135 - System.out.println( "Git name not set, setting it to default value." );
136 - runProcess( CWD, "git", "config", "--global", "user.name", "BuildTools" );
137 - }
138 - try
139 - {
140 - runProcess( CWD, "git", "config", "--global", "user.email" );
141 - } catch ( Exception ex )
142 - {
143 - System.out.println( "Git email not set, setting it to default value." );
144 - runProcess( CWD, "git", "config", "--global", "user.email", "unconfigured@null.spigotmc.org" );
145 - }
146 134
147 135 File workDir = new File( "work" );
148 136 workDir.mkdir();
149 137
150 138 File bukkit = new File( "Bukkit" );
151 139 if ( !bukkit.exists() )
152 140 {
153 141 clone( "https://hub.spigotmc.org/stash/scm/spigot/bukkit.git", bukkit );
154 142 }
155 143
164 152 {
165 153 clone( "https://hub.spigotmc.org/stash/scm/spigot/spigot.git", spigot );
166 154 }
167 155
168 156 File buildData = new File( "BuildData" );
169 157 if ( !buildData.exists() )
170 158 {
171 159 clone( "https://hub.spigotmc.org/stash/scm/spigot/builddata.git", buildData );
172 160 }
173 161
174 - File maven = new File( "apache-maven-3.2.3" );
175 - if ( !maven.exists() )
176 - {
177 - System.out.println( "Maven does not exist, downloading. Please wait." );
178 -
179 - File mvnTemp = new File( "mvn.zip" );
180 - mvnTemp.deleteOnExit();
181 -
182 - download( "http://static.spigotmc.org/maven/apache-maven-3.2.3-bin.zip", mvnTemp );
183 - unzip( mvnTemp, new File( "." ) );
184 - }
185 -
186 - String mvn = maven.getAbsolutePath() + "/bin/mvn";
187 -
188 162 Git bukkitGit = Git.open( bukkit );
189 163 Git craftBukkitGit = Git.open( craftBukkit );
190 164 Git spigotGit = Git.open( spigot );
191 165 Git buildGit = Git.open( buildData );
192 166
193 167 BuildInfo buildInfo = new BuildInfo( "Dev Build", "Development", 0, new BuildInfo.Refs( "master", "master", "master", "master" ) );
194 168
195 169 if ( !dontUpdate )
196 170 {
197 171 if ( !dev )
268 242
269 243 runProcess( CWD, "java", "-jar", "BuildData/bin/SpecialSource-2.jar", "map", "-i", vanillaJar.getPath(), "-m", "BuildData/mappings/" + versionInfo.getClassMappings(), "-o", clMappedJar.getPath() );
270 244
271 245 runProcess( CWD, "java", "-jar", "BuildData/bin/SpecialSource-2.jar", "map", "-i", clMappedJar.getPath(),
272 246 "-m", "BuildData/mappings/" + versionInfo.getMemberMappings(), "-o", mMappedJar.getPath() );
273 247
274 248 runProcess( CWD, "java", "-jar", "BuildData/bin/SpecialSource.jar", "-i", mMappedJar.getPath(), "--access-transformer", "BuildData/mappings/" + versionInfo.getAccessTransforms(),
275 249 "-m", "BuildData/mappings/" + versionInfo.getPackageMappings(), "-o", finalMappedJar.getPath() );
276 250 }
277 251
278 - runProcess( CWD, "sh", mvn, "install:install-file", "-Dfile=" + finalMappedJar, "-Dpackaging=jar", "-DgroupId=org.spigotmc",
252 + maven( CWD, "install:install-file", "-Dfile=" + finalMappedJar, "-Dpackaging=jar", "-DgroupId=org.spigotmc",
279 253 "-DartifactId=minecraft-server", "-Dversion=" + versionInfo.getMinecraftVersion() + "-SNAPSHOT" );
280 254
281 255 File decompileDir = new File( workDir, "decompile-" + mappingsVersion );
282 256 if ( !decompileDir.exists() )
283 257 {
284 258 decompileDir.mkdir();
285 259
286 260 File clazzDir = new File( decompileDir, "classes" );
287 261 unzip( finalMappedJar, clazzDir, new Predicate<String>()
288 262 {
289 263
290 264 @Override
291 265 public boolean apply(String input)
292 266 {
293 267 return input.startsWith( "net/minecraft/server" );
294 268 }
295 269 } );
296 270
297 - runProcess( CWD, "java", "-jar", "BuildData/bin/fernflower.jar", "-dgs=1", "-hdc=0", "-rbr=0", "-asc=1", "-udv=0", clazzDir.getPath(), decompileDir.getPath() );
271 + runProcess( CWD, "java", "-jar", "BuildData/bin/fernflower.jar", "-dgs=1", "-hdc=0", "-rbr=0", "-asc=1", "-udv=0", "-nls=1", clazzDir.getPath(), decompileDir.getPath() );
298 272 }
299 273
300 274 System.out.println( "Applying CraftBukkit Patches" );
301 275 File nmsDir = new File( craftBukkit, "src/main/java/net" );
302 276 if ( nmsDir.exists() )
303 277 {
304 278 System.out.println( "Backing up NMS dir" );
305 279 FileUtils.moveDirectory( nmsDir, new File( workDir, "nms.old." + System.currentTimeMillis() ) );
306 280 }
281 + System.setProperty( "line.separator", "\n" );
307 282 File patchDir = new File( craftBukkit, "nms-patches" );
308 283 for ( File file : patchDir.listFiles() )
309 284 {
310 285 String targetFile = "net/minecraft/server/" + file.getName().replaceAll( ".patch", ".java" );
311 286
312 287 File clean = new File( decompileDir, targetFile );
313 288 File t = new File( nmsDir.getParentFile(), targetFile );
314 289 t.getParentFile().mkdirs();
315 290
316 291 System.out.println( "Patching with " + file.getName() );
363 338 if ( !spigotServer.exists() )
364 339 {
365 340 clone( "file://" + craftBukkit.getAbsolutePath(), spigotServer );
366 341 }
367 342
368 343 // Git spigotApiGit = Git.open( spigotApi );
369 344 // Git spigotServerGit = Git.open( spigotServer );
370 345 if ( !skipCompile )
371 346 {
372 347 System.out.println( "Compiling Bukkit" );
373 - runProcess( bukkit, "sh", mvn, "clean", "install" );
348 + maven( bukkit, "clean", "install" );
374 349 if ( generateDocs )
375 350 {
376 - runProcess( bukkit, "sh", mvn, "javadoc:jar" );
351 + maven( bukkit, "javadoc:jar" );
377 352 }
378 353 if ( generateSource )
379 354 {
380 - runProcess( bukkit, "sh", mvn, "source:jar" );
355 + maven( bukkit, "source:jar" );
381 356 }
382 357
383 358 System.out.println( "Compiling CraftBukkit" );
384 - runProcess( craftBukkit, "sh", mvn, "clean", "install" );
359 + maven( craftBukkit, "clean", "install" );
385 360 }
386 361
387 362 try
388 363 {
389 - runProcess( spigot, "bash", "applyPatches.sh" );
364 + if (!bash)
365 + {
366 + applyPatches(
367 + bukkit,
368 + spigotApi,
369 + new File( spigot, "Spigot-API" ),
370 + new File( spigot, "Bukkit-Patches" ),
371 + "master"
372 + );
373 + applyPatches(
374 + craftBukkit,
375 + spigotServer,
376 + new File( spigot, "Spigot-Server" ),
377 + new File( spigot, "CraftBukkit-Patches" ),
378 + "patched"
379 + );
380 + } else
381 + {
382 + runProcess( spigot, "bash", "applyPatches.sh" );
383 + }
390 384 System.out.println( "*** Spigot patches applied!" );
391 385 System.out.println( "Compiling Spigot & Spigot-API" );
392 386
393 387 if ( !skipCompile )
394 388 {
395 - runProcess( spigot, "sh", mvn, "clean", "install" );
389 + maven( spigot, "clean", "install" );
396 390 }
397 391 } catch ( Exception ex )
398 392 {
399 393 System.err.println( "Error compiling Spigot, are you running this jar via msysgit?" );
400 394 ex.printStackTrace();
401 395 System.exit( 1 );
402 396 }
403 397
404 398 for ( int i = 0; i < 35; i++ )
405 399 {
406 400 System.out.println( " " );
407 401 }
408 402 System.out.println( "Success! Everything compiled successfully. Copying final .jar files now." );
409 403 copyJar( "CraftBukkit/target", "craftbukkit", "craftbukkit-" + versionInfo.getMinecraftVersion() + ".jar" );
410 404 copyJar( "Spigot/Spigot-Server/target", "spigot", "spigot-" + versionInfo.getMinecraftVersion() + ".jar" );
411 405 }
412 406
407 + public static void applyPatches(File base, File orig, File target, File patches, String branch) throws Exception
408 + {
409 + System.out.println( "Applying patches to " + target );
410 + Git gitOrig = Git.open( orig );
411 +
412 + gitOrig.fetch()
413 + .setRemote( "file://" + base.getAbsolutePath() )
414 + .setRefSpecs( new RefSpec( "refs/heads/*:refs/remotes/origin/*" ) )
415 + .call();
416 + gitOrig.reset()
417 + .setRef( "origin/" + branch )
418 + .setMode( ResetCommand.ResetType.HARD )
419 + .call();
420 + gitOrig.branchCreate()
421 + .setName( "upstream" )
422 + .setForce( true )
423 + .call();
424 +
425 + clone( orig.toURI().toString(), target );
426 + Git git = Git.open( target );
427 +
428 + StoredConfig config = git.getRepository().getConfig();
429 + config.setString( "remote", "upstream", "url", "file://" + orig.getAbsolutePath() );
430 + config.save();
431 +
432 + git.branchCreate()
433 + .setName( "master" )
434 + .setForce( true )
435 + .call();
436 + git.checkout()
437 + .setName( "master" )
438 + .call();
439 + git.fetch()
440 + .setRemote( "upstream" )
441 + .setRefSpecs( new RefSpec( "refs/heads/*:refs/remotes/upstream/*" ) )
442 + .call();
443 + git.reset()
444 + .setRef( "refs/remotes/upstream/upstream" )
445 + .setMode( ResetCommand.ResetType.HARD )
446 + .call();
447 + git.clean().setCleanDirectories( true ).call();
448 +
449 + File[] ps = patches.listFiles();
450 + Arrays.sort( ps );
451 + for ( File patch : ps )
452 + {
453 + if ( !patch.getName().endsWith( ".patch" ) ) continue;
454 + System.out.println( "Applying " + patch.getName() );
455 +
456 + String patchTxt = Files.toString( patch, Charsets.UTF_8 );
457 + patchTxt = patchTxt.replaceAll( "\r", "" );
458 + byte[] bytes = patchTxt.getBytes( Charsets.UTF_8 );
459 + List<File> files = git.apply()
460 + .setPatch( new ByteArrayInputStream( bytes ) )
461 + .call().getUpdatedFiles();
462 + AddCommand add = git.add();
463 + for (File file : files)
464 + {
465 + add.addFilepattern( target.toURI().relativize( file.toURI() ).getPath() );
466 + }
467 + add.call();
468 + SpigotPatch spigotPatch = new SpigotPatch( patch );
469 + git.commit()
470 + .setAuthor( spigotPatch.getAuthor() )
471 + .setMessage( spigotPatch.getMessage() )
472 + .call();
473 + }
474 + }
475 +
413 476 public static final String get(String url) throws IOException
414 477 {
415 478 URLConnection con = new URL( url ).openConnection();
416 479 con.setConnectTimeout( 5000 );
417 480 con.setReadTimeout( 5000 );
418 481
419 482 InputStreamReader r = null;
420 483 try
421 484 {
422 485 r = new InputStreamReader( con.getInputStream() );
459 522 System.out.println( "Successfully fetched updates!" );
460 523
461 524 repo.reset().setRef( ref ).setMode( ResetCommand.ResetType.HARD ).call();
462 525 if ( ref.equals( "master" ) )
463 526 {
464 527 repo.reset().setRef( "origin/master" ).setMode( ResetCommand.ResetType.HARD ).call();
465 528 }
466 529 System.out.println( "Checked out: " + ref );
467 530 }
468 531
532 + public static int maven(File workDir, String... command) throws Exception
533 + {
534 + File maven = new File( "apache-maven-3.2.3" );
535 + if ( !maven.exists() )
536 + {
537 + System.out.println( "Maven does not exist, downloading. Please wait." );
538 +
539 + File mvnTemp = new File( "mvn.zip" );
540 + mvnTemp.deleteOnExit();
541 +
542 + download( "http://static.spigotmc.org/maven/apache-maven-3.2.3-bin.zip", mvnTemp );
543 + unzip( mvnTemp, new File( "." ) );
544 + }
545 +
546 + String mvn = maven.getAbsolutePath() + "/bin/mvn";
547 +
548 + int extra = 2;
549 + if ( IS_WINDOWS )
550 + {
551 + extra = 1;
552 + }
553 +
554 + String[] args = new String[ extra + command.length ];
555 +
556 + if ( IS_WINDOWS ) {
557 + args[ 0 ] = mvn + ".bat";
558 + } else
559 + {
560 + args[ 0 ] = "sh";
561 + args[ 1 ] = mvn;
562 + }
563 + System.arraycopy( command, 0, args, extra, command.length );
564 + return runProcess( workDir, args );
565 + }
566 +
469 567 public static int runProcess(File workDir, String... command) throws Exception
470 568 {
471 569 ProcessBuilder pb = new ProcessBuilder( command );
472 570 pb.directory( workDir );
473 571 pb.environment().put( "JAVA_HOME", System.getProperty( "java.home" ) );
474 572 if ( !pb.environment().containsKey( "MAVEN_OPTS" ) )
475 573 {
476 574 pb.environment().put( "MAVEN_OPTS", "-Xmx1024M" );
477 575 }
478 576
558 656 } finally
559 657 {
560 658 is.close();
561 659 os.close();
562 660 }
563 661
564 662 System.out.println( "Extracted: " + outFile );
565 663 }
566 664 }
567 665
568 - public static void clone(String url, File target) throws GitAPIException
666 + public static void clone(String url, File target) throws Exception
569 667 {
570 668 System.out.println( "Starting clone of " + url + " to " + target );
571 669
572 - Git result = Git.cloneRepository().setURI( url ).setDirectory( target ).call();
670 + // Git result = Git.cloneRepository().setURI( url ).setDirectory( target ).call();
671 + Repository repo = Git.init().setDirectory( target ).call().getRepository();
672 + StoredConfig c = repo.getConfig();
673 + if (c.getString( "user", null, "name" ) == null)
674 + {
675 + c.setString( "user", null, "name", "BuildTools" );
676 + }
677 + if (c.getString( "user", null, "email" ) == null)
678 + {
679 + c.setString( "user", null, "email", "unconfigured@null.spigotmc.org" );
680 + }
681 + c.setEnum( "core", null, "autocrlf", CoreConfig.AutoCRLF.FALSE );
682 + URIish u = new URIish( url );
683 + RemoteConfig config = new RemoteConfig( repo.getConfig(), "origin" );
684 + config.addURI( u );
685 + String dst = "refs/remotes/" + config.getName() + "/*";
686 + RefSpec spec = new RefSpec();
687 + spec = spec.setForceUpdate( true );
688 + spec = spec.setSourceDestination( "refs/heads/*", dst );
689 +
690 + config.addFetchRefSpec( spec );
691 + config.update( c );
692 + c.save();
693 +
694 + Git result = new Git( repo );
695 + result.fetch()
696 + .setRemote( "origin" )
697 + .setTagOpt( TagOpt.FETCH_TAGS )
698 + .call();
699 +
700 + result.branchCreate()
701 + .setForce( true )
702 + .setStartPoint( "origin/master" )
703 + .setName( "master" )
704 + .call();
705 +
706 + result.checkout()
707 + .setForce( true )
708 + .setStartPoint( "origin/master" )
709 + .setName( "master" )
710 + .call();
573 711
574 712 try
575 713 {
576 714 System.out.println( "Cloned git repository " + url + " to " + target.getAbsolutePath() + ". Current HEAD: " + commitHash( result ) );
577 715
578 716 } finally
579 717 {
580 718 result.close();
581 719 }
582 720 }

Everything looks good. We'll let you know here if there's anything you should know about.

Add shortcut