Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Studio provisioning #530

Open
wants to merge 6 commits into
base: IdeProvisioning
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -3,23 +3,29 @@
import kotlin.io.FilesKt;
import org.gradle.profiler.ide.idea.IDEA;
import org.gradle.profiler.ide.idea.IDEAProvider;
import org.gradle.profiler.ide.studio.AndroidStudio;
import org.gradle.profiler.ide.studio.AndroidStudioProvider;

import java.io.File;
import java.nio.file.Path;

public class DefaultIdeProvider implements IdeProvider<Ide> {

private final IDEAProvider ideaProvider;
private final AndroidStudioProvider studioProvider;

public DefaultIdeProvider(IDEAProvider ideaProvider) {
public DefaultIdeProvider(IDEAProvider ideaProvider, AndroidStudioProvider studioProvider) {
this.ideaProvider = ideaProvider;
this.studioProvider = studioProvider;
}

@Override
public File provideIde(Ide ide, Path homeDir, Path downloadsDir) {
File result;
if (ide instanceof IDEA) {
result = ideaProvider.provideIde((IDEA) ide, homeDir, downloadsDir);
} else if (ide instanceof AndroidStudio) {
result = studioProvider.provideIde((AndroidStudio) ide, homeDir, downloadsDir);
} else {
throw new IllegalArgumentException("Unknown IDE to provide");
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
package org.gradle.profiler.ide;

import org.jetbrains.annotations.Nullable;

import java.io.File;

public class UnpackUtils {

@Nullable
public static File getSingleFileFrom(File dir) {
File[] unpackedFiles = dir.listFiles();
if (unpackedFiles == null || unpackedFiles.length == 0) {
return null;
}
if (unpackedFiles.length == 1) {
return unpackedFiles[0];
}
throw new IllegalStateException("Unexpected content in " + dir);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
import com.intellij.ide.starter.ide.installer.IdeInstallerFile;
import com.intellij.ide.starter.models.IdeInfo;
import org.gradle.profiler.ide.IdeProvider;
import org.jetbrains.annotations.Nullable;
import org.gradle.profiler.ide.UnpackUtils;

import java.io.File;
import java.nio.file.Path;
Expand Down Expand Up @@ -47,7 +47,7 @@ public File provideIde(IDEA ide, Path homeDir, Path downloadsDir) {
.resolve(version)
.toFile();

File unpackedIde = getUnpackedIde(unpackDir);
File unpackedIde = UnpackUtils.getSingleFileFrom(unpackDir);

if (unpackedIde != null) {
System.out.println("Downloading is skipped, get " + ideInfo.getFullName() + " from cache");
Expand All @@ -57,18 +57,6 @@ public File provideIde(IDEA ide, Path homeDir, Path downloadsDir) {
IdeInstallerFile installerFile = ideDownloader.downloadIdeInstaller(ideInfo, downloadsDir);
ideArchiveExtractor.unpackIdeIfNeeded(installerFile.getInstallerFile().toFile(), unpackDir);

return unpackDir.listFiles()[0];
}

@Nullable
private static File getUnpackedIde(File unpackDir) {
File[] unpackedFiles = unpackDir.listFiles();
if (unpackedFiles == null || unpackedFiles.length == 0) {
return null;
}
if (unpackedFiles.length == 1) {
return unpackedFiles[0];
}
throw new IllegalStateException("Unexpected content in " + unpackDir);
return UnpackUtils.getSingleFileFrom(unpackDir);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
package org.gradle.profiler.ide.studio;

import org.gradle.profiler.ide.Ide;
import org.jetbrains.annotations.NotNull;

public class AndroidStudio implements Ide {
private final String version;

public AndroidStudio(String version) {
this.version = version;
}

@Override
public @NotNull String getVersion() {
return version;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
package org.gradle.profiler.ide.studio;

import com.intellij.ide.starter.ide.IdeArchiveExtractor;
import com.intellij.ide.starter.utils.HttpClient;
import com.intellij.openapi.util.SystemInfo;
import org.gradle.profiler.ide.IdeProvider;
import org.gradle.profiler.ide.UnpackUtils;

import java.io.File;
import java.nio.file.Path;

public class AndroidStudioProvider implements IdeProvider<AndroidStudio> {
private final IdeArchiveExtractor ideArchiveExtractor = IdeArchiveExtractor.INSTANCE;
private final HttpClient httpClient = HttpClient.INSTANCE;

@Override
public File provideIde(AndroidStudio ide, Path homeDir, Path downloadsDir) {
if (ide.getVersion().isEmpty()) {
throw new IllegalArgumentException("Android Studio version must be specified");
}

String extension = getExtension();
String version = ide.getVersion();
File unpackDir = homeDir
.resolve("androidStudio")
.resolve(version)
.toFile();

File unpackedIde = UnpackUtils.getSingleFileFrom(unpackDir);

if (unpackedIde != null) {
System.out.println("Downloading is skipped, get Android Studio from cache");
return unpackedIde;
}

File installer = downloadsDir
.resolve("androidStudio" + version + extension)
.toFile();

httpClient.download(getStudioDownloadUrl(ide, extension), installer, 3);
ideArchiveExtractor.unpackIdeIfNeeded(installer, unpackDir);

return UnpackUtils.getSingleFileFrom(unpackDir);
}

private static String getExtension() {
if (SystemInfo.isWindows) {
return "windows.zip";
} else if (SystemInfo.isLinux) {
return "linux.tar.gz";
} else if (SystemInfo.isMac && SystemInfo.OS_ARCH.equals("aarch64")) {
return "mac_arm.zip";
} else if (SystemInfo.isMac) {
return "mac.zip";
} else {
throw new IllegalArgumentException("Unknown OS");
}
}

private static String getStudioDownloadUrl(AndroidStudio studio, String extension) {
return String.format("https://redirector.gvt1.com/edgedl/android/studio/ide-zips/%1$s/android-studio-%1$s-%2$s", studio.getVersion(), extension);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,31 +3,38 @@ package org.gradle.profiler.ide

import org.gradle.profiler.ide.idea.IDEA
import org.gradle.profiler.ide.idea.IDEAProvider
import org.gradle.profiler.ide.studio.AndroidStudio
import org.gradle.profiler.ide.studio.AndroidStudioProvider

class IdeProviderTest extends AbstractIdeProvisioningTest {

def "can provide IDEA"() {
def "can provide #title"() {
given:
def workDir = tmpDir.newFolder().toPath().toAbsolutePath()
def downloadsDir = workDir.resolve("downloads")
def ideHomeDir = workDir.resolve("ide")
def ideProvider = new DefaultIdeProvider(new IDEAProvider())
def ideProvider = new DefaultIdeProvider(new IDEAProvider(), new AndroidStudioProvider())

when:
def ide = ideProvider.provideIde(IDEA.LATEST, ideHomeDir, downloadsDir)
def ideFile = ideProvider.provideIde(ide, ideHomeDir, downloadsDir)

then:
outputContains("Downloading https://")
ide.exists()
ideFile.exists()

when:
def ide2 = ideProvider.provideIde(IDEA.LATEST, ideHomeDir, downloadsDir)
def ideFile2 = ideProvider.provideIde(ide, ideHomeDir, downloadsDir)

then:
outputContains("Downloading is skipped, get IDEA Community from cache")
ide == ide2
outputContains("Downloading is skipped, get $title from cache")
ideFile == ideFile2

and:
!downloadsDir.toFile().exists()

where:
ide | title
IDEA.LATEST | "IDEA Community"
new AndroidStudio("2023.2.1.16") | "Android Studio"
}
}