src/Pure/Tools/scala_project.scala
changeset 74071 b25b7c264a93
parent 74070 a69a13c4b049
child 74103 3b56d00ac333
equal deleted inserted replaced
74070:a69a13c4b049 74071:b25b7c264a93
    33     val contexts = Scala_Build.component_contexts() ::: plugin_contexts()
    33     val contexts = Scala_Build.component_contexts() ::: plugin_contexts()
    34 
    34 
    35     val jars1 = Path.split(Isabelle_System.getenv("ISABELLE_CLASSPATH"))
    35     val jars1 = Path.split(Isabelle_System.getenv("ISABELLE_CLASSPATH"))
    36     val jars2 = contexts.flatMap(_.requirements)
    36     val jars2 = contexts.flatMap(_.requirements)
    37 
    37 
    38     val jar_files =
    38     val jars =
    39       Library.distinct(jars1 ::: jars2).filterNot(path => contexts.exists(_.is_module(path)))
    39       Library.distinct(jars1 ::: jars2).filterNot(path => contexts.exists(_.is_module(path)))
    40 
    40 
    41     val source_files =
    41     val sources =
    42       (for {
    42       (for {
    43         context <- contexts.iterator
    43         context <- contexts.iterator
    44         path <- context.sources.iterator
    44         path <- context.sources.iterator
    45         if path.is_scala || path.is_java
    45         if path.is_scala || path.is_java
    46       } yield path).toList
    46       } yield path).toList
    47 
    47 
    48     (jar_files, source_files)
    48     (jars, sources)
    49   }
    49   }
    50 
    50 
    51   lazy val isabelle_scala_files: Map[String, Path] =
    51   lazy val isabelle_scala_files: Map[String, Path] =
    52   {
    52   {
    53     val context = Scala_Build.context(Path.ISABELLE_HOME, component = true)
    53     val context = Scala_Build.context(Path.ISABELLE_HOME, component = true)
    90   }
    90   }
    91 
    91 
    92 
    92 
    93   /* scala project */
    93   /* scala project */
    94 
    94 
       
    95   val default_project_dir = Path.explode("$ISABELLE_HOME_USER/scala_project")
       
    96 
    95   def package_dir(source_file: Path): Option[Path] =
    97   def package_dir(source_file: Path): Option[Path] =
    96   {
    98   {
    97     val lines = split_lines(File.read(source_file))
    99     val lines = split_lines(File.read(source_file))
    98     val Package = """\s*\bpackage\b\s*(?:object\b\s*)?((?:\w|\.)+)\b.*""".r
   100     val Package = """\s*\bpackage\b\s*(?:object\b\s*)?((?:\w|\.)+)\b.*""".r
    99     lines.collectFirst(
   101     lines.collectFirst(
   105   }
   107   }
   106 
   108 
   107   def the_package_dir(source_file: Path): Path =
   109   def the_package_dir(source_file: Path): Path =
   108     package_dir(source_file) getOrElse error("Failed to guess package from " + source_file)
   110     package_dir(source_file) getOrElse error("Failed to guess package from " + source_file)
   109 
   111 
   110   def scala_project(project_dir: Path, symlinks: Boolean = false): Unit =
   112   def scala_project(
   111   {
   113     project_dir: Path = default_project_dir,
   112     if (project_dir.is_file || project_dir.is_dir)
   114     more_sources: List[Path] = Nil,
   113       error("Project directory already exists: " + project_dir)
   115     symlinks: Boolean = false,
   114 
   116     force: Boolean = false,
   115     val java_src_dir = Isabelle_System.make_directory(project_dir + Path.explode("src/main/java"))
   117     progress: Progress = new Progress): Unit =
   116     val scala_src_dir = Isabelle_System.make_directory(project_dir + Path.explode("src/main/scala"))
   118   {
   117 
   119     if (project_dir.file.exists) {
   118     val (jar_files, source_files) = isabelle_files
   120       val detect =
       
   121         project_dir.is_dir &&
       
   122         (project_dir + Path.explode("build.gradle")).is_file &&
       
   123         (project_dir + Path.explode("src/main/scala")).is_dir
       
   124 
       
   125       if (force && detect) {
       
   126         progress.echo("Purging existing project directory: " + project_dir.absolute)
       
   127         Isabelle_System.rm_tree(project_dir)
       
   128       }
       
   129       else error("Project directory already exists: " + project_dir.absolute)
       
   130     }
       
   131 
       
   132     progress.echo("Creating project directory: " + project_dir.absolute)
       
   133     Isabelle_System.make_directory(project_dir)
       
   134 
       
   135     val java_src_dir = Isabelle_System.make_directory(Path.explode("src/main/java"))
       
   136     val scala_src_dir = Isabelle_System.make_directory(Path.explode("src/main/scala"))
       
   137 
       
   138     val (jars, sources) = isabelle_files
   119     isabelle_scala_files
   139     isabelle_scala_files
   120 
   140 
   121     for (source <- source_files) {
   141     for (source <- sources ::: more_sources) {
   122       val dir = if (source.is_java) java_src_dir else scala_src_dir
   142       val dir = (if (source.is_java) java_src_dir else scala_src_dir) + the_package_dir(source)
   123       val target = dir + the_package_dir(source)
   143       val target_dir = project_dir + dir
   124       Isabelle_System.make_directory(target)
   144       if (!target_dir.is_dir) {
   125       if (symlinks) Isabelle_System.symlink(source, target, native = true)
   145         progress.echo("  Creating package directory: " + dir)
   126       else Isabelle_System.copy_file(source, target)
   146         Isabelle_System.make_directory(target_dir)
       
   147       }
       
   148       if (symlinks) Isabelle_System.symlink(source.absolute, target_dir, native = true)
       
   149       else Isabelle_System.copy_file(source, target_dir)
   127     }
   150     }
   128 
   151 
   129     File.write(project_dir + Path.explode("settings.gradle"), "rootProject.name = 'Isabelle'\n")
   152     File.write(project_dir + Path.explode("settings.gradle"), "rootProject.name = 'Isabelle'\n")
   130     File.write(project_dir + Path.explode("build.gradle"),
   153     File.write(project_dir + Path.explode("build.gradle"),
   131 """plugins {
   154 """plugins {
   137 }
   160 }
   138 
   161 
   139 dependencies {
   162 dependencies {
   140   implementation 'org.scala-lang:scala-library:""" + scala.util.Properties.versionNumberString + """'
   163   implementation 'org.scala-lang:scala-library:""" + scala.util.Properties.versionNumberString + """'
   141   compile files(
   164   compile files(
   142     """ + jar_files.map(jar => groovy_string(File.platform_path(jar))).mkString("", ",\n    ", ")") +
   165     """ + jars.map(jar => groovy_string(File.platform_path(jar))).mkString("", ",\n    ", ")") +
   143 """
   166 """
   144 }
   167 }
   145 """)
   168 """)
   146   }
   169   }
   147 
   170 
   150 
   173 
   151   val isabelle_tool =
   174   val isabelle_tool =
   152     Isabelle_Tool("scala_project", "setup Gradle project for Isabelle/Scala/jEdit",
   175     Isabelle_Tool("scala_project", "setup Gradle project for Isabelle/Scala/jEdit",
   153       Scala_Project.here, args =>
   176       Scala_Project.here, args =>
   154     {
   177     {
       
   178       var project_dir = default_project_dir
   155       var symlinks = false
   179       var symlinks = false
       
   180       var force = false
   156 
   181 
   157       val getopts = Getopts("""
   182       val getopts = Getopts("""
   158 Usage: isabelle scala_project [OPTIONS] PROJECT_DIR
   183 Usage: isabelle scala_project [OPTIONS] [MORE_SOURCES ...]
   159 
   184 
   160   Options are:
   185   Options are:
   161     -L           make symlinks to original scala files
   186     -D DIR       project directory (default: """ + default_project_dir + """)
       
   187     -L           make symlinks to original source files
       
   188     -f           force update of existing directory
   162 
   189 
   163   Setup Gradle project for Isabelle/Scala/jEdit --- to support Scala IDEs
   190   Setup Gradle project for Isabelle/Scala/jEdit --- to support Scala IDEs
   164   such as IntelliJ IDEA.
   191   such as IntelliJ IDEA.
   165 """,
   192 """,
   166         "L" -> (_ => symlinks = true))
   193         "D:" -> (arg => project_dir = Path.explode(arg)),
       
   194         "L" -> (_ => symlinks = true),
       
   195         "f" -> (_ => force = true))
   167 
   196 
   168       val more_args = getopts(args)
   197       val more_args = getopts(args)
   169 
   198 
   170       val project_dir =
   199       val more_sources = more_args.map(Path.explode)
   171         more_args match {
   200       val progress = new Console_Progress
   172           case List(dir) => Path.explode(dir)
   201 
   173           case _ => getopts.usage()
   202       scala_project(project_dir = project_dir, more_sources = more_sources,
   174         }
   203         symlinks = symlinks, force = force, progress = progress)
   175 
       
   176       scala_project(project_dir, symlinks = symlinks)
       
   177     })
   204     })
   178 }
   205 }