diff -r e40f287c25c4 -r 820cf124dced src/Pure/Tools/scala_project.scala --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/Pure/Tools/scala_project.scala Wed Jan 15 15:05:33 2020 +0100 @@ -0,0 +1,143 @@ +/* Title: Pure/Tools/scala_project.scala + Author: Makarius + +Setup Gradle project for Isabelle/Scala/jEdit. +*/ + +package isabelle + + +object Scala_Project +{ + /* groovy syntax */ + + def groovy_string(s: String): String = + { + s.map(c => + c match { + case '\t' | '\b' | '\n' | '\r' | '\f' | '\\' | '\'' | '"' => "\\" + c + case _ => c.toString + }).mkString("'", "", "'") + } + + + /* file and directories */ + + def isabelle_files(): List[String] = + { + val files1 = + { + val isabelle_home = Path.explode("~~").canonical + Path.split(Isabelle_System.getenv("ISABELLE_CLASSPATH")). + map(path => File.relative_path(isabelle_home, path).getOrElse(path).implode) + } + + val files2 = + (for { + path <- + List( + Path.explode("~~/lib/classes/Pure.shasum"), + Path.explode("~~/src/Tools/jEdit/dist/Isabelle-jEdit.shasum")) + line <- Library.trim_split_lines(File.read(path)) + name = + if (line.length > 42 && line(41) == '*') line.substring(42) + else error("Bad shasum entry: " + quote(line)) + if name != "lib/classes/Pure.jar" && + name != "src/Tools/jEdit/dist/jars/Isabelle-jEdit-base.jar" && + name != "src/Tools/jEdit/dist/jars/Isabelle-jEdit.jar" + } yield name) + + files1 ::: files2 + } + + val isabelle_dirs: List[(String, Path)] = + List( + "src/Pure/" -> Path.explode("isabelle"), + "src/Tools/Graphview/" -> Path.explode("isabelle.graphview"), + "src/Tools/VSCode/" -> Path.explode("isabelle.vscode"), + "src/Tools/jEdit/src-base/" -> Path.explode("isabelle.jedit_base"), + "src/Tools/jEdit/src/" -> Path.explode("isabelle.jedit")) + + + /* scala project */ + + def scala_project(project_dir: Path, symlinks: Boolean = false) + { + if (symlinks && Platform.is_windows) + error("Cannot create symlinks on Windows") + + if (project_dir.is_file || project_dir.is_dir) + error("Project directory already exists: " + project_dir) + + val src_dir = project_dir + Path.explode("src/main/scala") + Isabelle_System.mkdirs(src_dir) + + val files = isabelle_files() + + for (file <- files if file.endsWith(".scala")) { + val (path, target) = + isabelle_dirs.collectFirst({ + case (prfx, p) if file.startsWith(prfx) => + (Path.explode("~~") + Path.explode(file), src_dir + p) + }).getOrElse(error("Unknown directory prefix for " + quote(file))) + + Isabelle_System.mkdirs(target) + if (symlinks) File.link(path, target) else File.copy(path, target) + } + + val jars = + for (file <- files if file.endsWith(".jar")) + yield { + if (file.startsWith("/")) file + else Isabelle_System.getenv("ISABELLE_HOME") + "/" + file + } + + File.write(project_dir + Path.explode("settings.gradle"), "rootProject.name = 'Isabelle'\n") + File.write(project_dir + Path.explode("build.gradle"), +"""plugins { + id 'scala' +} + +repositories { + mavenCentral() +} + +dependencies { + implementation 'org.scala-lang:scala-library:""" + scala.util.Properties.versionNumberString + """' + compile files( + """ + jars.map(jar => groovy_string(File.platform_path(jar))).mkString("", ",\n ", ")") + +""" +} +""") + } + + + /* Isabelle tool wrapper */ + + val isabelle_tool = + Isabelle_Tool("scala_project", "setup Gradle project for Isabelle/Scala/jEdit", args => + { + var symlinks = false + + val getopts = Getopts(""" +Usage: isabelle scala_project [OPTIONS] PROJECT_DIR + + Options are: + -l make symlinks to original scala files + + Setup Gradle project for Isabelle/Scala/jEdit --- to support Scala IDEs + such as IntelliJ IDEA. +""", + "l" -> (_ => symlinks = true)) + + val more_args = getopts(args) + + val project_dir = + more_args match { + case List(dir) => Path.explode(dir) + case _ => getopts.usage() + } + + scala_project(project_dir, symlinks = symlinks) + }) +}