merged
authorwenzelm
Thu, 17 Feb 2022 19:40:30 +0100
changeset 75084 f700ca53e3ae
parent 75081 d76b150efdc2 (current diff)
parent 75083 35a5c4b16024 (diff)
child 75085 ccc3a72210e6
merged
--- a/etc/build.props	Wed Feb 16 14:35:33 2022 +0100
+++ b/etc/build.props	Thu Feb 17 19:40:30 2022 +0100
@@ -221,6 +221,7 @@
   src/Tools/VSCode/src/vscode_model.scala \
   src/Tools/VSCode/src/vscode_rendering.scala \
   src/Tools/VSCode/src/vscode_resources.scala \
+  src/Tools/VSCode/src/vscode_setup.scala \
   src/Tools/VSCode/src/vscode_spell_checker.scala \
   src/Tools/jEdit/src/active.scala \
   src/Tools/jEdit/src/base_plugin.scala \
--- a/src/Pure/System/isabelle_tool.scala	Wed Feb 16 14:35:33 2022 +0100
+++ b/src/Pure/System/isabelle_tool.scala	Thu Feb 17 19:40:30 2022 +0100
@@ -233,4 +233,5 @@
   Build_Zipperposition.isabelle_tool,
   Check_Sources.isabelle_tool,
   Components.isabelle_tool,
-  isabelle.vscode.Build_VSCode.isabelle_tool)
+  isabelle.vscode.Build_VSCode.isabelle_tool,
+  isabelle.vscode.VSCode_Setup.isabelle_tool)
--- a/src/Pure/System/platform.scala	Wed Feb 16 14:35:33 2022 +0100
+++ b/src/Pure/System/platform.scala	Thu Feb 17 19:40:30 2022 +0100
@@ -44,6 +44,11 @@
       else if (platform == macos) "x86_64-darwin"
       else if (platform == windows) "x86_64-cygwin"
       else error("Bad platform family: " + quote(platform.toString))
+
+    def native(platform: Value): String =
+      if (platform == macos) "arm64-darwin"
+      else if (platform == windows) "x86_64-windows"
+      else standard(platform)
   }
 
 
--- a/src/Pure/Tools/scala_project.scala	Wed Feb 16 14:35:33 2022 +0100
+++ b/src/Pure/Tools/scala_project.scala	Thu Feb 17 19:40:30 2022 +0100
@@ -29,15 +29,12 @@
 
     def package_dir(source_file: Path): Path =
     {
-      val is_java = source_file.is_java
       val dir =
         package_name(source_file) match {
-          case Some(name) =>
-            if (is_java) Path.explode(space_explode('.', name).mkString("/"))
-            else Path.basic(name)
+          case Some(name) => Path.explode(space_explode('.', name).mkString("/"))
           case None => error("Failed to guess package from " + source_file)
         }
-      (if (is_java) java_src_dir else scala_src_dir) + dir
+      (if (source_file.is_java) java_src_dir else scala_src_dir) + dir
     }
   }
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/Tools/VSCode/etc/settings	Thu Feb 17 19:40:30 2022 +0100
@@ -0,0 +1,5 @@
+# -*- shell-script -*- :mode=shellscript:
+
+ISABELLE_VSCODE_VERSION="1.64.2"
+ISABELLE_VSCODE_HOME="$ISABELLE_HOME/src/Tools/VSCode"
+ISABELLE_VSCODE_SETTINGS="$ISABELLE_HOME_USER/vscode"
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/Tools/VSCode/src/vscode_setup.scala	Thu Feb 17 19:40:30 2022 +0100
@@ -0,0 +1,146 @@
+/*  Title:      Tools/VSCode/src/vscode_setup.scala
+    Author:     Makarius
+
+Setup VSCode from VSCodium distribution.
+*/
+
+package isabelle.vscode
+
+
+import isabelle._
+
+
+object VSCode_Setup
+{
+  /* global resources */
+
+  def vscode_home: Path = Path.variable("ISABELLE_VSCODE_HOME")
+  def vscode_settings: Path = Path.variable("ISABELLE_VSCODE_SETTINGS")
+  def vscode_version: String = Isabelle_System.getenv_strict("ISABELLE_VSCODE_VERSION")
+  def vscode_platform: Platform.Family.Value = Platform.family
+
+  def vscode_installation(version: String, platform: Platform.Family.Value): (Boolean, Path) =
+    {
+      val platform_name =
+        if (platform == Platform.Family.windows) Platform.Family.native(platform)
+        else Platform.Family.standard(platform)
+      val install_dir =
+        vscode_settings + Path.basic("installation") +
+          Path.basic(version) + Path.basic(platform_name)
+      val install_ok = (install_dir + Path.explode("bin/codium")).is_file
+      (install_ok, install_dir)
+    }
+
+
+  /* vscode setup */
+
+  val default_download_url: String = "https://github.com/VSCodium/vscodium/releases/download"
+
+  def download_name(version: String, platform: Platform.Family.Value): String =
+  {
+    val a = "VSCodium"
+    val (b, c) =
+      platform match {
+        case Platform.Family.linux_arm => ("linux-arm64", "tar.gz")
+        case Platform.Family.linux => ("linux-x64", "tar.gz")
+        case Platform.Family.macos => ("darwin-x64", "zip")
+        case Platform.Family.windows => ("win32-x64", "zip")
+      }
+    a + "-" + b + "-" + version + "." + c
+  }
+
+  def vscode_setup(
+    check: Boolean = false,
+    download_url: String = default_download_url,
+    version: String = vscode_version,
+    platform: Platform.Family.Value = vscode_platform,
+    verbose: Boolean = false,
+    progress: Progress = new Progress): Unit =
+  {
+    val (install_ok, install_dir) = vscode_installation(version, platform)
+
+    if (check) {
+      if (install_ok) progress.echo(install_dir.expand.implode)
+      else {
+        error("Bad Isabelle/VSCode installation: " + install_dir.expand +
+          "\n(use \"isabelle vscode_setup\" to download it)")
+      }
+    }
+    else {
+      if (install_ok) {
+        progress.echo_warning("Isabelle/VSCode installation already present: " + install_dir.expand)
+      }
+
+      val name = download_name(version, platform)
+      val is_zip = name.endsWith(".zip")
+      if (is_zip) Isabelle_System.require_command("unzip", test = "-h")
+
+      Isabelle_System.make_directory(install_dir)
+      Isabelle_System.with_tmp_file("download")(download =>
+        {
+          Isabelle_System.download_file(download_url + "/" + version + "/" + name, download,
+            progress = if (verbose) progress else new Progress)
+          if (verbose) progress.echo("Installing " + install_dir.expand)
+          if (is_zip) {
+            Isabelle_System.bash("unzip -x " + File.bash_path(download),
+              cwd = install_dir.file).check
+          }
+          else {
+            Isabelle_System.gnutar("-xzf " + File.bash_path(download),
+              dir = install_dir).check
+          }
+          if (platform == Platform.Family.windows) {
+            val files1 = File.find_files((install_dir + Path.explode("bin")).file)
+            val files2 =
+              File.find_files(install_dir.file,
+                pred = file => file.getName.endsWith(".exe") || file.getName.endsWith(".dll"))
+            for (file <- files1 ::: files2) File.set_executable(File.path(file), true)
+          }
+        })
+    }
+  }
+
+
+  /* Isabelle tool wrapper */
+
+  val isabelle_tool =
+    Isabelle_Tool("vscode_setup", "setup VSCode from VSCodium distribution",
+      Scala_Project.here, args =>
+    {
+      var check = false
+      var download_url = default_download_url
+      var version = vscode_version
+      var platform = vscode_platform
+      var verbose = false
+
+      val getopts = Getopts("""
+Usage: vscode_setup [OPTIONS]
+
+  Options are:
+    -C           check and print installation directory
+    -U URL       download URL
+                 (default: """" + default_download_url + """")
+    -V VERSION   version (default: """" + vscode_version + """")
+    -p NAME      platform family: """ + commas_quote(Platform.Family.list.map(_.toString)) + """
+                 (default: """ + quote(vscode_platform.toString) + """)
+    -v           verbose
+
+  Maintain local installation of VSCode, see also https://vscodium.com
+
+  Option -C checks the existing installation (without download), and
+  prints its directory location.
+""",
+        "C" -> (_ => check = true),
+        "U:" -> (arg => download_url = arg),
+        "V:" -> (arg => version = arg),
+        "p:" -> (arg => platform = Platform.Family.parse(arg)),
+        "v" -> (_ => verbose = true))
+
+      val more_args = getopts(args)
+      if (more_args.nonEmpty) getopts.usage()
+
+      val progress = new Console_Progress()
+      vscode_setup(check = check, download_url = download_url, version = version,
+        platform = platform, verbose = verbose, progress = progress)
+    })
+}