diff --git a/ReadMe.md b/ReadMe.md index 1338d3d..93cc6a9 100644 --- a/ReadMe.md +++ b/ReadMe.md @@ -1,7 +1,7 @@ IJP ImageJ Launcher =================== -IJP ImageJ Launcher is native launcher that starts [ImageJ 2] or [Fiji]. +IJP ImageJ Launcher is a native launcher that starts [ImageJ 2] or [Fiji]. It is intended to be a general drop-in replacement for the original [ImageJ Launcher]. IJP ImageJ Launcher is a clean implementation on the core function of starting [ImageJ 2] or [Fiji]. @@ -25,16 +25,16 @@ Features [work in progress] - Mac OS X Arm64 (Apple Silicon) - Mac OS X Intel - Linux -* Selects location of ImageJ directory +* Selects location of the ImageJ directory - Startup directory or - Directory specified by `--ij-dir` command line option * Locates Java Virtual Machine for ImageJ: - - Use Java VM requested the by the use (`--java-home`) + - Use Java VM requested by the user (`--java-home`) - Use `JAVA_HOME` environment variable - Search ImageJ directory for available Java executables * Determines the amount of memory used by JVM based on total system memory use 75% of the max * Determines available `imagej-launcher*.jar` -* Performs updates pending after last time ImageJ was closed +* Performs updates pending after the last time ImageJ was closed ### Full list of command line options @@ -45,7 +45,6 @@ Features [work in progress] --info informational output --debug verbose output --java-home specify JAVA_HOME explicitly - --print-java-home print ImageJ's idea of JAVA_HOME --ij-dir set the ImageJ directory to (used to find jars/, plugins/ and macros/) ``` diff --git a/src/main/scala/ij_plugins/imagej_launcher/Launcher.scala b/src/main/scala/ij_plugins/imagej_launcher/Launcher.scala index a440600..ce1ce49 100644 --- a/src/main/scala/ij_plugins/imagej_launcher/Launcher.scala +++ b/src/main/scala/ij_plugins/imagej_launcher/Launcher.scala @@ -17,7 +17,7 @@ class Launcher(logger: Logger): private val jarsDirName = "jars" def run(config: Config): Unit = - createCommandLine(config) match + prepareLaunch(config) match case Right(commandLine) => if config.dryRun then logger.debug("dry-run") @@ -27,9 +27,10 @@ class Launcher(logger: Logger): case Left(errorMessage) => logger.error(errorMessage) - private def createCommandLine(config: Config): Either[String, Seq[String]] = + private def prepareLaunch(config: Config): Either[String, Seq[String]] = for ijDir <- locateIJDir(config) + _ <- Updater.update(Path(ijDir), config.dryRun, logger) launcherJar <- findImageJLauncherJar(ijDir) javaExe <- locateJavaExecutable(config, ijDir) systemType <- determineSystemType() diff --git a/src/main/scala/ij_plugins/imagej_launcher/Main.scala b/src/main/scala/ij_plugins/imagej_launcher/Main.scala index de4000e..355f25c 100644 --- a/src/main/scala/ij_plugins/imagej_launcher/Main.scala +++ b/src/main/scala/ij_plugins/imagej_launcher/Main.scala @@ -58,10 +58,6 @@ object Main: .action((path, c) => c.copy(javaHome = Option(path))) .text("specify JAVA_HOME explicitly"), // - opt[Unit]("print-java-home") - .action((_, c) => c.copy(dryRun = true)) - .text("print ImageJ's idea of JAVA_HOME"), - // opt[File]("ij-dir") .valueName("") .action((path, c) => c.copy(ijDir = Option(path))) diff --git a/src/main/scala/ij_plugins/imagej_launcher/Updater.scala b/src/main/scala/ij_plugins/imagej_launcher/Updater.scala new file mode 100644 index 0000000..20aa03d --- /dev/null +++ b/src/main/scala/ij_plugins/imagej_launcher/Updater.scala @@ -0,0 +1,60 @@ +package ij_plugins.imagej_launcher + +import os.Path + +import scala.util.control.NonFatal + +object Updater: + + /** + * Perform update using files in `update` subdirectory, if it exists. + * @param ijDir imagej + * @param dryRun locate files to process but do not make any changes, but count the files that would be processed + * @param logger configured logger + * @return Number of files processed or an error message. + */ + def update(ijDir: Path, dryRun: Boolean, logger: Logger): Either[String, Long] = + try + val updateDir = ijDir / "update" + // Count used only for debug info + var count = 0 + if os.exists(updateDir) then + logger.info("Performing update..") + os.walk(updateDir) + .filter(os.isFile) + .foreach { src => + val dst = ijDir / src.relativeTo(updateDir) + if os.size(src) == 0 then + logger.debug(s"remove: $dst") + if !dryRun then os.remove(dst) + logger.debug(s"remove: $src") + if !dryRun then os.remove(src) + else + logger.debug(s"move : $src -> $dst") + if !dryRun then os.move(src, dst, replaceExisting = true, createFolders = true) + count += 1 + } + logger.debug(s"Delete update directory: $updateDir") + if !dryRun then deleteEmptyDirs(updateDir, logger) + Right(count) + else + logger.info("No update found") + Right(count) + catch + case NonFatal(ex) => + ex.printStackTrace() + Left(s"Failed to perform update: ${ex.getMessage} - ${ex.getClass.getSimpleName}") + + private def deleteEmptyDirs(dir: Path, logger: Logger): Unit = + logger.debug(s"Cleaning directory: $dir") + os.list(dir) + .filter(os.isDir) + .foreach(p => deleteEmptyDirs(p, logger)) + + if os.list(dir).isEmpty then + logger.debug(s"Removing empty dir: $dir") + os.remove(dir) + else + logger.debug(s"Cannot delete directory, not empty: $dir") + +end Updater diff --git a/src/test/scala/ij_plugins/imagej_launcher/UpdaterDemo.scala b/src/test/scala/ij_plugins/imagej_launcher/UpdaterDemo.scala new file mode 100644 index 0000000..6e7f24a --- /dev/null +++ b/src/test/scala/ij_plugins/imagej_launcher/UpdaterDemo.scala @@ -0,0 +1,9 @@ +package ij_plugins.imagej_launcher + +import os.Path + +@main +def updaterDemo(ijDir: String): Unit = + Updater.update(Path(ijDir), dryRun = false, new Logger(Logger.Level.Debug)) match + case Right(count) => println(s"Processed $count files") + case Left(error) => println(s"Failed with error: $error")