-
Notifications
You must be signed in to change notification settings - Fork 166
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
Add azd intellij plugin into azure-toolkit-for-intellij #9712
base: develop
Are you sure you want to change the base?
Changes from 5 commits
f55ec9d
df1adf4
71f51cd
08a98ae
1a46ee5
bb779d2
273965f
695355a
bd67768
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
dependencies { | ||
intellijPlatform { | ||
bundledPlugin("org.jetbrains.plugins.terminal") | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,69 @@ | ||
package com.microsoft.azure.toolkit.intellij.azd.actions; | ||
|
||
import com.intellij.openapi.actionSystem.AnAction; | ||
import com.intellij.openapi.actionSystem.AnActionEvent; | ||
import com.intellij.openapi.actionSystem.CommonDataKeys; | ||
import com.intellij.openapi.project.Project; | ||
import com.intellij.openapi.ui.Messages; | ||
import com.intellij.openapi.vfs.VirtualFile; | ||
import com.intellij.terminal.ui.TerminalWidget; | ||
import com.microsoft.azure.toolkit.intellij.azd.utils.AzdCliUtils; | ||
import org.jetbrains.annotations.NotNull; | ||
import org.jetbrains.plugins.terminal.TerminalToolWindowManager; | ||
|
||
import java.util.Set; | ||
|
||
public abstract class AzdCommandAction extends AnAction { | ||
|
||
@Override | ||
public void actionPerformed(@NotNull AnActionEvent event) { | ||
Project project = event.getProject(); | ||
if (project == null) return; | ||
|
||
VirtualFile file = event.getData(CommonDataKeys.VIRTUAL_FILE); | ||
if (file == null) return; | ||
|
||
String directory = file.getParent() != null ? file.getParent().getPath() : null; | ||
if (directory == null) return; | ||
|
||
String command = event.getPresentation().getDescription(); | ||
if (command == null || command.isEmpty()) return; | ||
|
||
// Check if azd installed | ||
if (AzdCliUtils.getAzdVersion() == null) { | ||
// Prompt the user to install azd | ||
int result = Messages.showYesNoDialog( | ||
project, | ||
"Azure Developer CLI is not installed. Would you like to install it?", | ||
"Install Azure Developer CLI", | ||
"Install", | ||
"Later", | ||
Messages.getQuestionIcon() | ||
); | ||
if (result == Messages.YES) { | ||
if (!AzdCliUtils.installAzdCli(project)) { | ||
return; | ||
} | ||
} else { | ||
return; | ||
} | ||
} | ||
|
||
// Create new terminal tab under the `directory` | ||
TerminalToolWindowManager terminalManager = TerminalToolWindowManager.getInstance(project); | ||
TerminalWidget terminal = terminalManager.createShellWidget(directory, command, true, true); | ||
|
||
// Run the command | ||
terminal.sendCommandToExecute(command); | ||
} | ||
|
||
@Override | ||
public void update(@NotNull AnActionEvent event) { | ||
VirtualFile file = event.getData(CommonDataKeys.VIRTUAL_FILE); | ||
// Only enable the action for specific files | ||
boolean enabled = file != null && getSupportedFiles().contains(file.getName()); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We enable the |
||
event.getPresentation().setEnabledAndVisible(enabled); | ||
} | ||
|
||
public abstract Set<String> getSupportedFiles(); | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
package com.microsoft.azure.toolkit.intellij.azd.actions; | ||
|
||
import java.util.Set; | ||
|
||
public class AzdInitCommandAction extends AzdCommandAction { | ||
|
||
@Override | ||
public Set<String> getSupportedFiles() { | ||
return Set.of("pom.xml"); | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
package com.microsoft.azure.toolkit.intellij.azd.actions; | ||
|
||
import java.util.Set; | ||
|
||
public class AzdUpCommandAction extends AzdCommandAction { | ||
|
||
@Override | ||
public Set<String> getSupportedFiles() { | ||
return Set.of("azure.yaml"); | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,151 @@ | ||
package com.microsoft.azure.toolkit.intellij.azd.utils; | ||
|
||
import com.google.gson.Gson; | ||
import com.intellij.execution.ExecutionException; | ||
import com.intellij.execution.configurations.GeneralCommandLine; | ||
import com.intellij.execution.process.OSProcessHandler; | ||
import com.intellij.execution.process.ProcessEvent; | ||
import com.intellij.execution.process.ProcessListener; | ||
import com.intellij.execution.process.ProcessOutput; | ||
import com.intellij.execution.process.ProcessOutputTypes; | ||
import com.intellij.openapi.diagnostic.Logger; | ||
import com.intellij.openapi.ui.Messages; | ||
import com.intellij.openapi.util.Key; | ||
import com.intellij.openapi.util.SystemInfo; | ||
import org.jetbrains.annotations.NotNull; | ||
import com.intellij.openapi.project.Project; | ||
|
||
import javax.annotation.Nullable; | ||
import java.util.concurrent.TimeUnit; | ||
|
||
public class AzdCliUtils { | ||
|
||
private static final Logger logger = Logger.getInstance(AzdCliUtils.class); | ||
|
||
private static final long CACHE_LIFETIME = 15 * 60 * 1000; // 15 minutes | ||
|
||
private static long lastCheckTime = 0; | ||
|
||
private static AzdVersion cachedAzdVersion = null; | ||
|
||
@Nullable | ||
public static AzdVersion getAzdVersion() { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This method is currently used to check if |
||
// Check if the cached result is still valid | ||
long currentTime = System.currentTimeMillis(); | ||
if (cachedAzdVersion != null && (currentTime - lastCheckTime) < CACHE_LIFETIME) { | ||
return cachedAzdVersion; | ||
} | ||
|
||
GeneralCommandLine commandLine = new GeneralCommandLine() | ||
.withExePath("azd") | ||
.withParameters("version", "--output", "json"); | ||
|
||
try { | ||
ProcessOutput output = runCommand(commandLine); | ||
|
||
if (output.getExitCode() == 0) { | ||
String stdout = output.getStdout(); | ||
Gson gson = new Gson(); | ||
AzdVersion azdVersion = gson.fromJson(stdout, AzdVersion.class); | ||
// Cache the result | ||
cachedAzdVersion = azdVersion; | ||
lastCheckTime = currentTime; | ||
|
||
return azdVersion; | ||
} else { | ||
logger.warn("Failed to check azd login status. Exit code: " + output.getExitCode()); | ||
} | ||
} catch (Exception e) { | ||
logger.warn("Unexpected error while checking azd login status", e); | ||
} | ||
|
||
return null; | ||
} | ||
|
||
public static class AzdVersion { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. |
||
|
||
private AzdVersionInfo azd; | ||
|
||
public AzdVersionInfo getAzd() { | ||
return azd; | ||
} | ||
|
||
public static class AzdVersionInfo { | ||
private String version; | ||
private String commit; | ||
|
||
public String getVersion() { | ||
return version; | ||
} | ||
|
||
public String getCommit() { | ||
return commit; | ||
} | ||
} | ||
} | ||
|
||
public static boolean installAzdCli(@NotNull Project project) { | ||
try { | ||
GeneralCommandLine commandLine = getInstallationCommandLine(); | ||
|
||
ProcessOutput output = runCommand(commandLine); | ||
|
||
if (output.getExitCode() == 0) { | ||
Messages.showInfoMessage(project, "Azure Developer CLI (azd) installed successfully!", "Installation Complete"); | ||
return true; | ||
} else { | ||
Messages.showErrorDialog(project, "Failed to install Azure Developer CLI (azd). Error: " + output.getStderr(), "Installation Failed"); | ||
return false; | ||
} | ||
} catch (Exception e) { | ||
Messages.showErrorDialog(project, "An error occurred while installing Azure Developer CLI (azd): " + e.getMessage(), "Installation Error"); | ||
} | ||
return false; | ||
} | ||
|
||
private static ProcessOutput runCommand(GeneralCommandLine commandLine) throws ExecutionException { | ||
OSProcessHandler processHandler = new OSProcessHandler(commandLine); | ||
ProcessOutput output = new ProcessOutput(); | ||
|
||
processHandler.addProcessListener(new ProcessListener() { | ||
@Override | ||
public void onTextAvailable(ProcessEvent event, Key outputType) { | ||
if (ProcessOutputTypes.STDOUT.equals(outputType)) { | ||
output.appendStdout(event.getText()); | ||
} else if (ProcessOutputTypes.STDERR.equals(outputType)) { | ||
output.appendStderr(event.getText()); | ||
} | ||
} | ||
|
||
@Override | ||
public void processTerminated(ProcessEvent event) { | ||
output.setExitCode(event.getExitCode()); | ||
} | ||
}); | ||
|
||
processHandler.startNotify(); | ||
processHandler.waitFor(TimeUnit.SECONDS.toMillis(30)); // Wait up to 30 seconds | ||
return output; | ||
} | ||
|
||
private static GeneralCommandLine getInstallationCommandLine() { | ||
GeneralCommandLine commandLine = new GeneralCommandLine(); | ||
|
||
// See https://aka.ms/azd-install | ||
if (SystemInfo.isWindows) { | ||
commandLine.withExePath("powershell") | ||
.withParameters("-ex", "AllSigned") | ||
.withParameters("-c", "Invoke-RestMethod 'https://aka.ms/install-azd.ps1' | Invoke-Expression"); | ||
} else if (SystemInfo.isLinux || SystemInfo.isMac) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Same command for Linux and Mac platforms. |
||
commandLine.withExePath("curl") | ||
.withParameters("-fsSL", "https://aka.ms/install-azd.sh") | ||
.withParameters("|", "bash"); | ||
} else { | ||
String osName = System.getProperty("os.name"); | ||
logger.error("Unsupported platform: " + osName); | ||
throw new UnsupportedOperationException("Unsupported platform: " + osName); | ||
} | ||
|
||
return commandLine; | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
<idea-plugin> | ||
<depends>com.intellij.modules.platform</depends> | ||
<depends>org.jetbrains.plugins.terminal</depends> | ||
|
||
<actions> | ||
<action id="Actions.AzdInit" class="com.microsoft.azure.toolkit.intellij.azd.actions.AzdInitCommandAction" | ||
text="Generate Azure Deployment Script (azd init)" description="azd init" | ||
icon="/icons/azd-logo.svg"> | ||
</action> | ||
<action id="Actions.AzdUp" class="com.microsoft.azure.toolkit.intellij.azd.actions.AzdUpCommandAction" | ||
text="Package, Provision, and Deploy to Azure (azd up)" description="azd up" | ||
icon="/icons/azd-logo.svg"> | ||
</action> | ||
</actions> | ||
</idea-plugin> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Install successfully first, then run
azd
commands in the terminal.