482 val linux_app = isabelle_target + Path.explode("contrib/linux_app") |
482 val linux_app = isabelle_target + Path.explode("contrib/linux_app") |
483 File.move(linux_app + Path.explode("Isabelle"), |
483 File.move(linux_app + Path.explode("Isabelle"), |
484 isabelle_target + Path.explode(isabelle_name)) |
484 isabelle_target + Path.explode(isabelle_name)) |
485 Isabelle_System.rm_tree(linux_app) |
485 Isabelle_System.rm_tree(linux_app) |
486 |
486 |
|
487 val archive_name = isabelle_name + "_linux.tar.gz" |
|
488 progress.echo("Packaging " + archive_name + " ...") |
|
489 execute_tar(tmp_dir, |
|
490 "-czf " + File.bash_path(release.dist_dir + Path.explode(archive_name)) + " " + |
|
491 Bash.string(isabelle_name)) |
|
492 |
487 case Platform.Family.macos => |
493 case Platform.Family.macos => |
488 File.move(isabelle_target + Path.explode("contrib/macos_app"), tmp_dir) |
|
489 File.write(isabelle_target + jedit_props, |
494 File.write(isabelle_target + jedit_props, |
490 File.read(isabelle_target + jedit_props) |
495 File.read(isabelle_target + jedit_props) |
491 .replaceAll("lookAndFeel=.*", "lookAndFeel=com.apple.laf.AquaLookAndFeel") |
496 .replaceAll("lookAndFeel=.*", "lookAndFeel=com.apple.laf.AquaLookAndFeel") |
492 .replaceAll("delete-line.shortcut=.*", "delete-line.shortcut=C+d") |
497 .replaceAll("delete-line.shortcut=.*", "delete-line.shortcut=C+d") |
493 .replaceAll("delete.shortcut2=.*", "delete.shortcut2=A+d") |
498 .replaceAll("delete.shortcut2=.*", "delete.shortcut2=A+d") |
494 .replaceAll("plugin-blacklist.MacOSX.jar=true", "plugin-blacklist.MacOSX.jar=")) |
499 .replaceAll("plugin-blacklist.MacOSX.jar=true", "plugin-blacklist.MacOSX.jar=")) |
495 |
500 |
|
501 |
|
502 // MacOS application bundle |
|
503 |
|
504 File.move(isabelle_target + Path.explode("contrib/macos_app"), tmp_dir) |
|
505 val dmg_dir = tmp_dir + Path.explode("macos_app/dmg") |
|
506 |
|
507 val isabelle_app = Path.explode(isabelle_name + ".app") |
|
508 val app_dir = dmg_dir + isabelle_app |
|
509 File.move(dmg_dir + Path.explode("Isabelle.app"), app_dir) |
|
510 |
|
511 val app_contents = app_dir + Path.explode("Contents") |
|
512 val app_resources = app_contents + Path.explode("Resources") |
|
513 File.move(tmp_dir + Path.explode(isabelle_name), app_resources) |
|
514 |
|
515 File.write(app_contents + Path.explode("Info.plist"), |
|
516 File.read(Path.explode("~~/Admin/MacOS/Info.plist")) |
|
517 .replaceAllLiterally("{ISABELLE_NAME}", isabelle_name) |
|
518 .replaceAllLiterally("{JAVA_OPTIONS}", |
|
519 terminate_lines(java_options.map(opt => "<string>" + opt + "</string>")))) |
|
520 |
|
521 for (cp <- classpath) { |
|
522 File.link( |
|
523 Path.explode("../Resources/" + isabelle_name + "/") + cp, |
|
524 app_contents + Path.explode("Java"), |
|
525 force = true) |
|
526 } |
|
527 |
|
528 File.link( |
|
529 Path.explode("../Resources/" + isabelle_name + "/contrib/" + |
|
530 jdk_component + "/x86_64-darwin"), |
|
531 app_contents + Path.explode("PlugIns/bundled.jdk"), |
|
532 force = true) |
|
533 |
|
534 File.link( |
|
535 Path.explode("../../Info.plist"), |
|
536 app_resources + Path.explode(isabelle_name + "/" + isabelle_name + ".plist"), |
|
537 force = true) |
|
538 |
|
539 File.link( |
|
540 Path.explode("Contents/Resources/" + isabelle_name), |
|
541 app_dir + Path.explode("Isabelle"), |
|
542 force = true) |
|
543 |
|
544 |
|
545 // application archive: dmg or .tar.gz |
|
546 |
|
547 val isabelle_dmg = Path.explode(isabelle_name + ".dmg") |
|
548 (release.dist_dir + isabelle_dmg).file.delete |
|
549 |
|
550 remote_mac match { |
|
551 case SSH.Target(user, host) => |
|
552 progress.echo("Packaging " + isabelle_dmg + " (via host " + quote(host) + ") ...") |
|
553 using(SSH.open_session(options, host = host, user = user))(ssh => |
|
554 { |
|
555 val dmg_archive = Path.explode("dmg.tar") |
|
556 execute_tar(dmg_dir, "-cf " + File.bash_path(tmp_dir + dmg_archive) + " .") |
|
557 |
|
558 ssh.with_tmp_dir(remote_dir => |
|
559 { |
|
560 val cd = "cd " + ssh.bash_path(remote_dir) + "; " |
|
561 ssh.write_file(remote_dir + dmg_archive, tmp_dir + dmg_archive) |
|
562 ssh.execute( |
|
563 cd + "mkdir dmg && tar -C dmg -xf " + ssh.bash_path(dmg_archive)).check |
|
564 ssh.execute( |
|
565 cd + "hdiutil create -srcfolder dmg -volname Isabelle " + |
|
566 ssh.bash_path(isabelle_dmg)).check |
|
567 ssh.read_file(remote_dir + isabelle_dmg, release.dist_dir + isabelle_dmg) |
|
568 }) |
|
569 }) |
|
570 case _ => |
|
571 val archive_name = isabelle_name + "_macos.tar.gz" |
|
572 progress.echo("Packaging " + archive_name + " ...") |
|
573 execute_tar(dmg_dir, |
|
574 "-czf " + File.bash_path(release.dist_dir + Path.explode(archive_name)) + " " + |
|
575 File.bash_path(isabelle_app)) |
|
576 } |
|
577 |
496 case Platform.Family.windows => |
578 case Platform.Family.windows => |
497 val app_template = Path.explode("~~/Admin/Windows/launch4j") |
|
498 val cygwin_template = Path.explode("~~/Admin/Windows/Cygwin") |
|
499 |
|
500 File.move(isabelle_target + Path.explode("contrib/windows_app"), tmp_dir) |
|
501 |
|
502 File.write(isabelle_target + jedit_props, |
579 File.write(isabelle_target + jedit_props, |
503 File.read(isabelle_target + jedit_props) |
580 File.read(isabelle_target + jedit_props) |
504 .replaceAll("lookAndFeel=.*", |
581 .replaceAll("lookAndFeel=.*", |
505 "lookAndFeel=com.sun.java.swing.plaf.windows.WindowsLookAndFeel") |
582 "lookAndFeel=com.sun.java.swing.plaf.windows.WindowsLookAndFeel") |
506 .replaceAll("foldPainter=.*", "foldPainter=Square")) |
583 .replaceAll("foldPainter=.*", "foldPainter=Square")) |
|
584 |
|
585 |
|
586 // application launcher |
|
587 |
|
588 File.move(isabelle_target + Path.explode("contrib/windows_app"), tmp_dir) |
|
589 |
|
590 val app_template = Path.explode("~~/Admin/Windows/launch4j") |
507 |
591 |
508 File.write(isabelle_target + Path.explode(isabelle_name + ".l4j.ini"), |
592 File.write(isabelle_target + Path.explode(isabelle_name + ".l4j.ini"), |
509 (java_options_title :: java_options).map(_ + "\r\n").mkString) |
593 (java_options_title :: java_options).map(_ + "\r\n").mkString) |
510 |
594 |
511 val isabelle_xml = Path.explode("isabelle.xml") |
595 val isabelle_xml = Path.explode("isabelle.xml") |
559 """> contrib/cygwin/isabelle/symlinks""") |
647 """> contrib/cygwin/isabelle/symlinks""") |
560 |
648 |
561 execute(isabelle_target, """find . -type l -exec rm "{}" ";" """) |
649 execute(isabelle_target, """find . -type l -exec rm "{}" ";" """) |
562 |
650 |
563 File.write(isabelle_target + Path.explode("contrib/cygwin/isabelle/uninitialized"), "") |
651 File.write(isabelle_target + Path.explode("contrib/cygwin/isabelle/uninitialized"), "") |
564 } |
652 |
565 |
653 |
566 |
654 // executable archive (self-extracting 7z) |
567 // archive |
655 |
568 |
|
569 val archive_name = isabelle_name + "_" + platform + ".tar.gz" |
|
570 progress.echo("Packaging " + archive_name + " ...") |
|
571 execute_tar(tmp_dir, |
|
572 "-czf " + File.bash_path(release.dist_dir + Path.explode(archive_name)) + " " + |
|
573 Bash.string(isabelle_name)) |
|
574 |
|
575 |
|
576 // platform-specific application (outside archive) |
|
577 |
|
578 progress.echo("Application for " + platform + " ...") |
|
579 |
|
580 platform match { |
|
581 case Platform.Family.linux => |
|
582 File.link( |
|
583 Path.explode(isabelle_name + "_linux.tar.gz"), |
|
584 release.dist_dir + Path.explode(isabelle_name + "_app.tar.gz"), |
|
585 force = true) |
|
586 |
|
587 case Platform.Family.macos => |
|
588 val dmg_dir = tmp_dir + Path.explode("macos_app/dmg") |
|
589 val app_dir = dmg_dir + Path.explode(isabelle_name + ".app") |
|
590 File.move(dmg_dir + Path.explode("Isabelle.app"), app_dir) |
|
591 |
|
592 val app_contents = app_dir + Path.explode("Contents") |
|
593 val app_resources = app_contents + Path.explode("Resources") |
|
594 File.move(tmp_dir + Path.explode(isabelle_name), app_resources) |
|
595 |
|
596 File.write(app_contents + Path.explode("Info.plist"), |
|
597 File.read(Path.explode("~~/Admin/MacOS/Info.plist")) |
|
598 .replaceAllLiterally("{ISABELLE_NAME}", isabelle_name) |
|
599 .replaceAllLiterally("{JAVA_OPTIONS}", |
|
600 terminate_lines(java_options.map(opt => "<string>" + opt + "</string>")))) |
|
601 |
|
602 for (cp <- classpath) { |
|
603 File.link( |
|
604 Path.explode("../Resources/" + isabelle_name + "/") + cp, |
|
605 app_contents + Path.explode("Java"), |
|
606 force = true) |
|
607 } |
|
608 |
|
609 File.link( |
|
610 Path.explode("../Resources/" + isabelle_name + "/contrib/" + |
|
611 jdk_component + "/x86_64-darwin"), |
|
612 app_contents + Path.explode("PlugIns/bundled.jdk"), |
|
613 force = true) |
|
614 |
|
615 File.link( |
|
616 Path.explode("../../Info.plist"), |
|
617 app_resources + Path.explode(isabelle_name + "/" + isabelle_name + ".plist"), |
|
618 force = true) |
|
619 |
|
620 File.link( |
|
621 Path.explode("Contents/Resources/" + isabelle_name), |
|
622 app_dir + Path.explode("Isabelle"), |
|
623 force = true) |
|
624 |
|
625 val dmg = Path.explode(isabelle_name + ".dmg") |
|
626 (release.dist_dir + dmg).file.delete |
|
627 |
|
628 val dmg_archive = Path.explode(isabelle_name + "_dmg.tar.gz") |
|
629 execute_tar(dmg_dir, "-czf " + File.bash_path(release.dist_dir + dmg_archive) + " .") |
|
630 |
|
631 remote_mac match { |
|
632 case SSH.Target(user, host) => |
|
633 progress.echo("Building dmg on " + quote(host) + " ...") |
|
634 using(SSH.open_session(options, host = host, user = user))(ssh => |
|
635 { |
|
636 ssh.with_tmp_dir(remote_dir => |
|
637 { |
|
638 val cd = "cd " + ssh.bash_path(remote_dir) + "; " |
|
639 ssh.write_file(remote_dir + dmg_archive, release.dist_dir + dmg_archive) |
|
640 ssh.execute( |
|
641 cd + "mkdir root && tar -C root -xzf " + ssh.bash_path(dmg_archive)).check |
|
642 ssh.execute( |
|
643 cd + "hdiutil create -srcfolder root -volname Isabelle " + |
|
644 ssh.bash_path(dmg)).check |
|
645 ssh.read_file(remote_dir + dmg, release.dist_dir + dmg) |
|
646 }) |
|
647 }) |
|
648 case _ => |
|
649 } |
|
650 |
|
651 case Platform.Family.windows => |
|
652 val exe_archive = tmp_dir + Path.explode(isabelle_name + ".7z") |
656 val exe_archive = tmp_dir + Path.explode(isabelle_name + ".7z") |
653 exe_archive.file.delete |
657 exe_archive.file.delete |
654 |
658 |
655 execute(tmp_dir, |
659 execute(tmp_dir, |
656 "7z -y -bd a " + File.bash_path(exe_archive) + " " + Bash.string(isabelle_name)) |
660 "7z -y -bd a " + File.bash_path(exe_archive) + " " + Bash.string(isabelle_name)) |
657 if (!exe_archive.is_file) error("Failed to create archive: " + exe_archive) |
661 if (!exe_archive.is_file) error("Failed to create archive: " + exe_archive) |
658 |
662 |
659 val isabelle_exe = Path.explode(isabelle_name + ".exe") |
|
660 val sfx_exe = tmp_dir + Path.explode("windows_app/7zsd_All_x64.sfx") |
663 val sfx_exe = tmp_dir + Path.explode("windows_app/7zsd_All_x64.sfx") |
661 val sfx_txt = |
664 val sfx_txt = |
662 File.read(Path.explode("~~/Admin/Windows/Installer/sfx.txt")). |
665 File.read(Path.explode("~~/Admin/Windows/Installer/sfx.txt")). |
663 replaceAllLiterally("{ISABELLE_NAME}", isabelle_name) |
666 replaceAllLiterally("{ISABELLE_NAME}", isabelle_name) |
664 |
667 |