Skip to content

Commit

Permalink
Add support for installing IntelliJ from .dmg (#283)
Browse files Browse the repository at this point in the history
* Add support for installing IntelliJ from .dmg

* Improve code style with try/finally and path resolving

* Fix - restore String type for val dmgDir

* update reference.conf user-facing comments

* Update core/driver/sources/src/main/resources/reference.conf

Co-authored-by: Paweł Lipski <[email protected]>

* Update core/driver/sources/src/main/resources/reference.conf

Co-authored-by: Paweł Lipski <[email protected]>

* PR fixes - improve code style and fix logic

* remove println

Co-authored-by: Paweł Lipski <[email protected]>
  • Loading branch information
LukaszKontowski and PawelLipski authored Oct 14, 2022
1 parent ac12752 commit 9d8d9a2
Show file tree
Hide file tree
Showing 3 changed files with 46 additions and 4 deletions.
8 changes: 5 additions & 3 deletions core/driver/sources/src/main/resources/reference.conf
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,10 @@ probe {

// `ext` stands for the file extension (file format). This config specifies which extension should be
// downloaded and installed. By default, ".zip" distributions of IntelliJ IDEA are downloaded. For now
// only ".zip" extension is supported.
// two extensions are supported: ".zip" and ".dmg". ".zip" is the default one whereas ".dmg" should be used
// for Mac OS X only.
ext = ".zip"
# ext = ".dmg"

}

Expand Down Expand Up @@ -96,8 +98,8 @@ probe {
// ]
//
// Moreover, you can add a pattern pointing to a directory of an installed IntelliJ instance instead of
// pattern pointing to a .zip file. ide-probe will recognize if the pattern points to a directory with
// installed IntelliJ or to a .zip file. For example, if you run the IntelliJ Plugin Verifier on your
// pattern pointing to a .zip (or .dmg) file. ide-probe will recognize if the pattern points to a directory with
// installed IntelliJ or to a .zip (or .dmg) file. For example, if you run the IntelliJ Plugin Verifier on your
// repository (https://plugins.jetbrains.com/docs/intellij/tools-gradle-intellij-plugin.html#tasks-runpluginverifier),
// then you could use following configuration:
// intellij.repositories = [
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@ import pureconfig.ConfigReader

import org.virtuslab.ideprobe.ConfigFormat
import org.virtuslab.ideprobe.Extensions._
import org.virtuslab.ideprobe.OS
import org.virtuslab.ideprobe.Shell

sealed trait Resource

Expand Down Expand Up @@ -86,6 +88,31 @@ object Resource extends ConfigFormat {
}
}

final class DMGFile(val path: Path) extends IntellijResource {
def installTo(target: Path): Unit = {
// create tmp directory where disk image will be attached
val dmgDirPath = Paths.get(System.getProperty("java.io.tmpdir")).createDirectory("dmg_dir")
dmgDirPath.createDirectory()
val dmgDir = dmgDirPath.toString

try {
// attach disk image from .dmg file to local filesystem
Shell.run("hdiutil", "attach", "-mountpoint", dmgDir, path.toString).assertSuccess()
// copy $dmgDir/IntelliJ IDEA CE.app/ to proper installation directory
val appDir = dmgDirPath
.directChildren()
.find(path => path.name.startsWith("IntelliJ IDEA") && path.name.endsWith(".app"))
.get // appDir should point to an existing path. If not - `get` will throw NoSuchElementException
val idePath = Paths.get(s"$dmgDir/${appDir.name}/Contents")
idePath.copyDir(target)
} finally {
// detach disk image from local filesystem
Shell.run("hdiutil", "detach", dmgDir).assertSuccess()
}

}
}

final class Plain(val path: Path) extends IntellijResource {
def installTo(target: Path): Unit = {
path.copyDir(target)
Expand All @@ -111,6 +138,12 @@ object Resource extends ConfigFormat {
}
}

object DMGFile {
def unapply(path: Path): Option[DMGFile] = {
if (path.toString.endsWith(".dmg") && OS.Current == OS.Mac) Some(new DMGFile(path)) else None
}
}

object Plain {
def unapply(path: Path): Option[Plain] = {
if (path.isDirectory) Some(new Plain(path)) else None
Expand All @@ -120,6 +153,7 @@ object Resource extends ConfigFormat {
implicit class ExtractorExtension(path: Path) {
def toExtracted: IntellijResource = path match {
case Archive(archive) => archive
case DMGFile(archive) => archive
case Plain(archive) => archive
case _ => throw new IllegalStateException(s"Not an archive: $path")
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import java.io.InputStream
import java.net.URI
import java.nio.file.Files
import java.nio.file.Path
import java.nio.file.Paths

import scala.annotation.tailrec

Expand Down Expand Up @@ -73,7 +74,12 @@ object ResourceProvider {
}

private def cached(uri: URI): Path = {
directory.resolve(Hash.md5(uri.toString))
val resultPath = directory.resolve(Hash.md5(uri.toString))
val uriExtensionIndex = uri.toString.lastIndexOf('.')
if (uriExtensionIndex != -1)
Paths.get(resultPath.toString + uri.toString.substring(uriExtensionIndex)) // keep extension in cached file name
else
resultPath
}
}
}

0 comments on commit 9d8d9a2

Please sign in to comment.