# HG changeset patch # User wenzelm # Date 1646585147 -3600 # Node ID bbbee54b119856583bc9ca251e76499c5b92a664 # Parent 075467e070bafd3faa29b30fa957e56c925024e7 prepare patched version more thoroughly, with explicit patches; diff -r 075467e070ba -r bbbee54b1198 src/Pure/Admin/build_vscodium.scala --- a/src/Pure/Admin/build_vscodium.scala Sun Mar 06 15:47:09 2022 +0100 +++ b/src/Pure/Admin/build_vscodium.scala Sun Mar 06 17:45:47 2022 +0100 @@ -7,6 +7,7 @@ package isabelle +import java.util.{Map => JMap} import java.security.MessageDigest import java.util.Base64 @@ -30,6 +31,8 @@ build_name: String, env: List[String]) { + def is_linux: Boolean = platform == Platform.Family.linux + def download_name: String = "VSCodium-" + download_template.replace("{VERSION}", version) def download_zip: Boolean = download_name.endsWith(".zip") @@ -42,7 +45,7 @@ Isabelle_System.download_file(vscodium_download + "/" + version + "/" + download_name, download_file, progress = progress) - progress.echo("Unpacking ...") + progress.echo("Extract ...") if (download_zip) { Isabelle_System.bash("unzip -x " + File.bash_path(download_file), cwd = dir.file).check } @@ -52,6 +55,20 @@ }) } + def get_vscodium_repository(vscodium_dir: Path, progress: Progress = new Progress): Unit = + { + progress.echo("Getting VSCodium repository ...") + Isabelle_System.bash( + List( + "set -e", + "git clone -n " + Bash.string(vscodium_repository) + " .", + "git checkout -q " + Bash.string(version) + ).mkString("\n"), cwd = vscodium_dir.file).check + + progress.echo("Getting VSCode repository version ...") + Isabelle_System.bash(environment + "\n" + "./get_repo.sh", cwd = vscodium_dir.file).check + } + def platform_dir(dir: Path): Path = { val platform_name = @@ -62,7 +79,7 @@ def build_dir(dir: Path): Path = dir + Path.explode(build_name) - def build_environment: String = + def environment: String = (("MS_TAG=" + Bash.string(version)) :: "SHOULD_BUILD=yes" :: "VSCODE_ARCH=x64" :: env) .map(s => "export " + s + "\n").mkString @@ -74,23 +91,40 @@ dir + Path.explode(resources) } - def patch_resources(base_dir: Path): Unit = + def patch_sources(base_dir: Path): String = + { + val dir = base_dir + Path.explode("vscode") + Isabelle_System.with_copy_dir(dir, dir.orig) { + for (name <- Seq("build/lib/electron.js", "build/lib/electron.ts")) { + File.change(dir + Path.explode(name), strict = true) { + _.replace("""'resources/darwin/' + icon + '.icns'""", + """'resources/darwin/' + icon.toLowerCase() + '.icns'""") + } + } + Isabelle_System.make_patch(base_dir, dir.base.orig, dir.base) + } + } + + def patch_resources(base_dir: Path): String = { val dir = resources_dir(base_dir) + Isabelle_System.with_copy_dir(dir, dir.orig) { + HTML.init_fonts(dir + Path.explode("app/out/vs/base/browser/ui")) - HTML.init_fonts(dir + Path.explode("app/out/vs/base/browser/ui")) + val workbench_css = dir + Path.explode("app/out/vs/workbench/workbench.desktop.main.css") + val checksum1 = file_checksum(workbench_css) + File.append(workbench_css, "\n\n" + HTML.fonts_css_dir(prefix = "../base/browser/ui")) + val checksum2 = file_checksum(workbench_css) - val workbench_css = dir + Path.explode("app/out/vs/workbench/workbench.desktop.main.css") - val checksum1 = file_checksum(workbench_css) - File.append(workbench_css, "\n\n" + HTML.fonts_css_dir(prefix = "../base/browser/ui")) - val checksum2 = file_checksum(workbench_css) + val file_name = workbench_css.file_name + File.change_lines(dir + Path.explode("app/product.json")) { _.map(line => + if (line.containsSlice(file_name) && line.contains(checksum1)) { + line.replace(checksum1, checksum2) + } + else line) + } - val file_name = workbench_css.file_name - File.change_lines(dir + Path.explode("app/product.json")) { _.map(line => - if (line.containsSlice(file_name) && line.contains(checksum1)) { - line.replace(checksum1, checksum2) - } - else line) + Isabelle_System.make_patch(dir.dir, dir.orig.base, dir.base) } } @@ -124,7 +158,7 @@ name.endsWith(".dll") || name.endsWith(".exe") || name.endsWith(".node") }) for (file <- files1 ::: files2) File.set_executable(File.path(file), true) - Isabelle_System.bash("chmod -R o-w " + File.bash_path(dir)) + Isabelle_System.bash("chmod -R o-w " + File.bash_path(dir)).check case _ => } } @@ -160,28 +194,59 @@ def the_platform_info(platform: Platform.Family.Value): Platform_Info = platform_infos.getOrElse(platform, error("No platform info for " + quote(platform.toString))) + def linux_platform_info: Platform_Info = + the_platform_info(Platform.Family.linux) + /* check system */ def check_system(platforms: List[Platform.Family.Value]): Unit = { - Linux.check_system() + if (Platform.family != Platform.Family.linux) error("Not a Linux/x86_64 system") Isabelle_System.require_command("git") - if (platforms.nonEmpty) { - Isabelle_System.require_command("node") - Isabelle_System.require_command("yarn") - Isabelle_System.require_command("jq") - } + Isabelle_System.require_command("node") + Isabelle_System.require_command("yarn") + Isabelle_System.require_command("jq") + if (platforms.contains(Platform.Family.windows)) { Isabelle_System.require_command("wine") } + if (platforms.exists(platform => the_platform_info(platform).download_zip)) { Isabelle_System.require_command("unzip", test = "-h") } } + /* original repository clones and patches */ + + def vscodium_patch(verbose: Boolean = false, progress: Progress = new Progress): String = + { + val platform_info = linux_platform_info + check_system(List(platform_info.platform)) + + Isabelle_System.with_tmp_dir("vscodium")(vscodium_dir => + { + platform_info.get_vscodium_repository(vscodium_dir, progress = progress) + val vscode_dir = vscodium_dir + Path.basic("vscode") + progress.echo("Prepare VSCodium ...") + Isabelle_System.with_copy_dir(vscode_dir, vscode_dir.orig) { + progress.bash( + List( + "set -e", + platform_info.environment, + "./prepare_vscode.sh", + // enforce binary diff of code.xpm + "cp vscode/resources/linux/code.png vscode/resources/linux/rpm/code.xpm" + ).mkString("\n"), cwd = vscodium_dir.file, echo = verbose).check + Isabelle_System.make_patch(vscodium_dir, vscode_dir.orig.base, vscode_dir.base, + diff_options = "--exclude=.git --exclude=node_modules") + } + }) + } + + /* build vscodium */ def default_platforms: List[Platform.Family.Value] = Platform.Family.list @@ -214,39 +279,47 @@ progress.echo("Component " + component_dir) + /* patches */ + + progress.echo("Building patches:") + + val patches_dir = Isabelle_System.new_directory(component_dir + Path.basic("patches")) + + def write_patch(name: String, patch: String): Unit = + File.write(patches_dir + Path.explode(name).patch, patch) + + write_patch("01-vscodium", vscodium_patch(verbose = verbose, progress = progress)) + + /* build */ - for (platform <- platforms) { + for (platform <- platforms) yield { val platform_info = the_platform_info(platform) - progress.echo("Building " + platform + " ...") - Isabelle_System.with_tmp_dir("vscodium")(vscodium_dir => { - def execute(lines: String*): Unit = - progress.bash(("set -e" :: platform_info.build_environment :: lines.toList).mkString("\n"), - cwd = vscodium_dir.file, echo = verbose).check + progress.echo("Building " + platform + ":") - execute( - "git clone -n " + Bash.string(vscodium_repository) + " .", - "git checkout -q " + Bash.string(version), - "./get_repo.sh") + platform_info.get_vscodium_repository(vscodium_dir, progress = progress) + + val sources_patch = platform_info.patch_sources(vscodium_dir) + if (platform_info.is_linux) write_patch("02-isabelle_sources", sources_patch) - for (name <- Seq("vscode/build/lib/electron.js", "vscode/build/lib/electron.ts")) { - File.change(vscodium_dir + Path.explode(name), strict = true) { - _.replace("""'resources/darwin/' + icon + '.icns'""", - """'resources/darwin/' + icon.toLowerCase() + '.icns'""") - } + progress.echo("Build VSCodium ...") + progress.bash(platform_info.environment + "\n" + "./build.sh", + cwd = vscodium_dir.file, echo = verbose).check + + if (platform_info.is_linux) { + Isabelle_System.copy_file(vscodium_dir + Path.explode("LICENSE"), component_dir) } - execute("./build.sh") - - Isabelle_System.copy_file(vscodium_dir + Path.explode("LICENSE"), component_dir) - val platform_dir = platform_info.platform_dir(component_dir) Isabelle_System.copy_dir(platform_info.build_dir(vscodium_dir), platform_dir) platform_info.node_binaries(platform_dir, progress) - platform_info.patch_resources(platform_dir) + + val resources_patch = platform_info.patch_resources(platform_dir) + if (platform_info.is_linux) write_patch("03-isabelle_resources", resources_patch) + platform_info.setup_executables(platform_dir) }) } @@ -280,8 +353,9 @@ "This is VSCodium " + version + " from " + vscodium_repository + """ -It has been built from sources using "isabelle build_vscodium": this applies -a few changes required for Isabelle/VSCode. +It has been built from sources using "isabelle build_vscodium". This applies +a few changes required for Isabelle/VSCode, see "patches" directory for a +formal record. Makarius diff -r 075467e070ba -r bbbee54b1198 src/Pure/General/path.scala --- a/src/Pure/General/path.scala Sun Mar 06 15:47:09 2022 +0100 +++ b/src/Pure/General/path.scala Sun Mar 06 17:45:47 2022 +0100 @@ -233,6 +233,7 @@ def tar: Path = ext("tar") def gz: Path = ext("gz") def log: Path = ext("log") + def orig: Path = ext("orig") def patch: Path = ext("patch") def backup: Path = diff -r 075467e070ba -r bbbee54b1198 src/Pure/System/isabelle_system.scala --- a/src/Pure/System/isabelle_system.scala Sun Mar 06 15:47:09 2022 +0100 +++ b/src/Pure/System/isabelle_system.scala Sun Mar 06 17:45:47 2022 +0100 @@ -196,6 +196,15 @@ } } + def with_copy_dir[A](dir1: Path, dir2: Path)(body: => A): A = + { + if (dir2.is_file || dir2.is_dir) error("Directory already exists: " + dir2.absolute) + else { + try { copy_dir(dir1, dir2); body } + finally { rm_tree(dir2 ) } + } + } + object Make_Directory extends Scala.Fun_Strings("make_directory") { @@ -437,12 +446,13 @@ else error("Expected to find GNU tar executable") } - def make_patch(base_dir: Path, src: Path, dst: Path): String = + def make_patch(base_dir: Path, src: Path, dst: Path, diff_options: String = ""): String = { with_tmp_file("patch")(patch => { Isabelle_System.bash( - "diff -ru " + File.bash_path(src) + " " + File.bash_path(dst) + " > " + File.bash_path(patch), + "diff -ru " + diff_options + " -- " + File.bash_path(src) + " " + File.bash_path(dst) + + " > " + File.bash_path(patch), cwd = base_dir.file).check_rc(_ <= 1) File.read(patch) })