Skip to content

Commit 419f087

Browse files
committed
Make flex deploy maven build aware (#638)
1 parent 951c0b1 commit 419f087

File tree

9 files changed

+427
-27
lines changed

9 files changed

+427
-27
lines changed

google-cloud-tools-plugin/build.gradle

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ sourceSets.test.resources.srcDirs = ['testResources']
2222

2323
intellij {
2424
pluginName = 'google-cloud-tools'
25-
plugins 'Groovy','gradle', 'git4idea', 'properties', 'junit'
25+
plugins 'Groovy', 'gradle', 'git4idea', 'properties', 'junit', 'maven'
2626

2727
publish {
2828
pluginId '8079'

google-cloud-tools-plugin/resources/META-INF/plugin.xml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ Code inspections for App Engine Java code.</description>
3434
<depends>org.jetbrains.plugins.gradle</depends>
3535
<depends>com.google.gct.login</depends>
3636
<depends>Git4Idea</depends>
37+
<depends>org.jetbrains.idea.maven</depends>
3738

3839
<application-components>
3940
<component>

google-cloud-tools-plugin/resources/messages/CloudToolsBundle.properties

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,7 @@ appengine.stop.modules.version.success.dialog.title=Application Stopped
6868
appengine.stop.modules.version.canceled.message=Undeploy Canceled
6969
appengine.deployment.error.during.staging=Deployment failed due to an unexpected error while creating the staging directory for deployment.
7070
appengine.deployment.error.not.logged.in=You must be logged in to perform this action.
71+
appengine.deployment.source.not.found.error=Invalid deployment source.
7172
appengine.deployment.status.deploying=Deploying to App Engine
7273
appengine.deployment.error.invalid.cloudsdk=Invalid Cloud SDK directory path.
7374
appengine.deployment.error.cancelled=Deployment process was cancelled.

google-cloud-tools-plugin/src/com/google/cloud/tools/intellij/CloudToolsPluginInitializationComponent.java

Lines changed: 39 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717

1818
import com.google.cloud.tools.intellij.appengine.cloud.AppEngineCloudType;
1919
import com.google.cloud.tools.intellij.appengine.cloud.AppEngineToolsMenuAction;
20+
import com.google.cloud.tools.intellij.appengine.cloud.MavenBuildDeploymentSourceType;
2021
import com.google.cloud.tools.intellij.appengine.cloud.UserSpecifiedPathDeploymentSourceType;
2122
import com.google.cloud.tools.intellij.debugger.CloudDebugConfigType;
2223

@@ -51,33 +52,51 @@ public String getComponentName() {
5152

5253
@Override
5354
public void initComponent() {
54-
CloudToolsPluginInfoService pluginInfoService = ServiceManager
55-
.getService(CloudToolsPluginInfoService.class);
5655
CloudToolsPluginConfigurationService pluginConfigurationService = ServiceManager
5756
.getService(CloudToolsPluginConfigurationService.class);
57+
CloudToolsPluginInfoService pluginInfoService = ServiceManager
58+
.getService(CloudToolsPluginInfoService.class);
59+
5860
if (pluginInfoService.shouldEnable(GctFeature.DEBUGGER)) {
59-
pluginConfigurationService
60-
.registerExtension(
61-
ConfigurationType.CONFIGURATION_TYPE_EP, new CloudDebugConfigType());
61+
initDebugger(pluginConfigurationService);
6262
}
63-
if (pluginInfoService.shouldEnable(GctFeature.APPENGINE_FLEX)) {
64-
AppEngineCloudType appEngineCloudType = new AppEngineCloudType();
65-
pluginConfigurationService.registerExtension(ServerType.EP_NAME, appEngineCloudType);
66-
pluginConfigurationService.registerExtension(DeploymentSourceType.EP_NAME,
67-
new UserSpecifiedPathDeploymentSourceType());
68-
pluginConfigurationService.registerExtension(ConfigurationType.CONFIGURATION_TYPE_EP,
69-
new DeployToServerConfigurationType(appEngineCloudType));
7063

71-
ActionManager actionManager = ActionManager.getInstance();
72-
AnAction toolsMenuAction = new AppEngineToolsMenuAction();
73-
actionManager.registerAction(AppEngineToolsMenuAction.ID , toolsMenuAction);
74-
DefaultActionGroup toolsMenu =
75-
(DefaultActionGroup) actionManager.getAction(AppEngineToolsMenuAction.GROUP_ID);
76-
toolsMenu.add(toolsMenuAction, Constraints.LAST);
64+
if (pluginInfoService.shouldEnable(GctFeature.APPENGINE_FLEX)) {
65+
initAppEngineFlex(pluginConfigurationService);
7766
}
67+
7868
if (pluginInfoService.shouldEnableErrorFeedbackReporting()) {
79-
pluginConfigurationService
80-
.enabledGoogleFeedbackErrorReporting(pluginInfoService.getPluginId());
69+
initErrorReporting(pluginConfigurationService, pluginInfoService);
8170
}
8271
}
72+
73+
private void initDebugger(CloudToolsPluginConfigurationService pluginConfigurationService) {
74+
pluginConfigurationService
75+
.registerExtension(
76+
ConfigurationType.CONFIGURATION_TYPE_EP, new CloudDebugConfigType());
77+
}
78+
79+
private void initAppEngineFlex(CloudToolsPluginConfigurationService pluginConfigurationService) {
80+
AppEngineCloudType appEngineCloudType = new AppEngineCloudType();
81+
pluginConfigurationService.registerExtension(ServerType.EP_NAME, appEngineCloudType);
82+
pluginConfigurationService.registerExtension(ConfigurationType.CONFIGURATION_TYPE_EP,
83+
new DeployToServerConfigurationType(appEngineCloudType));
84+
pluginConfigurationService.registerExtension(DeploymentSourceType.EP_NAME,
85+
new UserSpecifiedPathDeploymentSourceType());
86+
pluginConfigurationService.registerExtension(DeploymentSourceType.EP_NAME,
87+
new MavenBuildDeploymentSourceType());
88+
89+
ActionManager actionManager = ActionManager.getInstance();
90+
AnAction toolsMenuAction = new AppEngineToolsMenuAction();
91+
actionManager.registerAction(AppEngineToolsMenuAction.ID , toolsMenuAction);
92+
DefaultActionGroup toolsMenu =
93+
(DefaultActionGroup) actionManager.getAction(AppEngineToolsMenuAction.GROUP_ID);
94+
toolsMenu.add(toolsMenuAction, Constraints.LAST);
95+
}
96+
97+
private void initErrorReporting(CloudToolsPluginConfigurationService pluginConfigurationService,
98+
CloudToolsPluginInfoService pluginInfoService) {
99+
pluginConfigurationService
100+
.enabledGoogleFeedbackErrorReporting(pluginInfoService.getPluginId());
101+
}
83102
}

google-cloud-tools-plugin/src/com/google/cloud/tools/intellij/appengine/cloud/AppEngineDeploymentConfigurator.java

Lines changed: 29 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,8 @@
1818

1919
import com.google.cloud.tools.intellij.appengine.util.CloudSdkUtil;
2020

21+
import com.intellij.openapi.module.Module;
22+
import com.intellij.openapi.module.ModuleManager;
2123
import com.intellij.openapi.module.ModulePointer;
2224
import com.intellij.openapi.module.ModulePointerManager;
2325
import com.intellij.openapi.options.SettingsEditor;
@@ -31,6 +33,8 @@
3133

3234
import org.jetbrains.annotations.NotNull;
3335
import org.jetbrains.annotations.Nullable;
36+
import org.jetbrains.idea.maven.project.MavenProject;
37+
import org.jetbrains.idea.maven.project.MavenProjectsManager;
3438

3539
import java.io.File;
3640
import java.util.ArrayList;
@@ -52,20 +56,41 @@ public AppEngineDeploymentConfigurator(Project project) {
5256
@NotNull
5357
@Override
5458
public List<DeploymentSource> getAvailableDeploymentSources() {
55-
List<DeploymentSource> deploymentSources = new ArrayList<DeploymentSource>();
59+
List<DeploymentSource> deploymentSources = new ArrayList<>();
60+
61+
for (Module module : ModuleManager.getInstance(project).getModules()) {
62+
if (isJarOrWarMavenBuild(module)) {
63+
deploymentSources.add(
64+
new MavenBuildDeploymentSource(
65+
ModulePointerManager.getInstance(project).create(module), project));
66+
}
67+
}
5668

5769
ModulePointer modulePointer =
5870
ModulePointerManager.getInstance(project).create("userSpecifiedSource");
5971
deploymentSources.add(new UserSpecifiedPathDeploymentSource(modulePointer));
6072

6173
deploymentSources.addAll(JavaDeploymentSourceUtil
62-
.getInstance().createArtifactDeploymentSources(project, getJarsAndWars()));
74+
.getInstance().createArtifactDeploymentSources(project, getJarAndWarArtifacts()));
6375

6476
return deploymentSources;
6577
}
6678

67-
private List<Artifact> getJarsAndWars() {
68-
List<Artifact> jarsAndWars = new ArrayList<Artifact>();
79+
private boolean isJarOrWarMavenBuild(Module module) {
80+
MavenProjectsManager projectsManager = MavenProjectsManager.getInstance(project);
81+
MavenProject mavenProject = projectsManager.findProject(module);
82+
83+
boolean isMavenProject = projectsManager.isMavenizedModule(module)
84+
&& mavenProject != null;
85+
86+
return isMavenProject &&
87+
("jar".equalsIgnoreCase(mavenProject.getPackaging())
88+
|| "war".equalsIgnoreCase(mavenProject.getPackaging()));
89+
90+
}
91+
92+
private List<Artifact> getJarAndWarArtifacts() {
93+
List<Artifact> jarsAndWars = new ArrayList<>();
6994
for (Artifact artifact : ArtifactManager.getInstance(project).getArtifacts()) {
7095
if (artifact.getArtifactType().getId().equalsIgnoreCase("jar")
7196
|| artifact.getArtifactType().getId().equalsIgnoreCase("war")) {

google-cloud-tools-plugin/src/com/google/cloud/tools/intellij/appengine/cloud/AppEngineRuntimeInstance.java

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -72,8 +72,11 @@ public void deploy(@NotNull final DeploymentTask<AppEngineDeploymentConfiguratio
7272

7373
final AppEngineDeployAction deployAction;
7474
AppEngineDeploymentConfiguration deploymentConfig = task.getConfiguration();
75-
File deploymentSource = deploymentConfig.isUserSpecifiedArtifact() ?
76-
new File(deploymentConfig.getUserSpecifiedArtifactPath()) : task.getSource().getFile();
75+
File deploymentSource = task.getSource().getFile();
76+
if (deploymentSource == null) {
77+
callback.errorOccurred(GctBundle.message("appengine.deployment.source.not.found.error"));
78+
return;
79+
}
7780

7881
if (deploymentConfig.getConfigType() == ConfigType.AUTO) {
7982
deployAction = appEngineHelper.createAutoDeploymentAction(
Lines changed: 168 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,168 @@
1+
/*
2+
* Copyright (C) 2016 The Android Open Source Project
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package com.google.cloud.tools.intellij.appengine.cloud;
18+
19+
import com.intellij.execution.BeforeRunTask;
20+
import com.intellij.execution.RunManagerEx;
21+
import com.intellij.execution.configurations.RunConfiguration;
22+
import com.intellij.execution.impl.ConfigurationSettingsEditorWrapper;
23+
import com.intellij.ide.DataManager;
24+
import com.intellij.openapi.actionSystem.DataContext;
25+
import com.intellij.openapi.module.Module;
26+
import com.intellij.openapi.project.Project;
27+
import com.intellij.remoteServer.configuration.deployment.ModuleDeploymentSource;
28+
import com.intellij.remoteServer.impl.configuration.deployment.DeployToServerRunConfiguration;
29+
import com.intellij.remoteServer.impl.configuration.deployment.ModuleDeploymentSourceType;
30+
31+
import org.jetbrains.annotations.NotNull;
32+
import org.jetbrains.annotations.Nullable;
33+
34+
import java.util.Collection;
35+
import java.util.List;
36+
37+
import javax.swing.JComponent;
38+
39+
/**
40+
* Base class for build-system (e.g. maven or gradle) deployment source types. Deployment
41+
* sources for specific build-systems should extend this providing the build-system specific
42+
* implementations.
43+
*/
44+
public abstract class BuildDeploymentSourceType extends ModuleDeploymentSourceType {
45+
46+
/**
47+
* Creates a pre-deploy task ({@link BeforeRunTask}) for the given build-system and attaches it
48+
* to this module deployment source type. Invoked when a new deployment configuration is created.
49+
*
50+
* Provides the common functionality for creating the build-system packaging task,
51+
* delegating build-system specific functions to the concrete sub-types.
52+
*
53+
* Only creates a new task if one is not already configured.
54+
*/
55+
@Override
56+
public void setBuildBeforeRunTask(
57+
@NotNull RunConfiguration configuration,
58+
@NotNull ModuleDeploymentSource source) {
59+
60+
Module module = source.getModule();
61+
62+
if (module == null) {
63+
return;
64+
}
65+
66+
setConfiguration(configuration);
67+
68+
RunManagerEx runManager = RunManagerEx.getInstanceEx(configuration.getProject());
69+
final Collection<? extends BeforeRunTask> buildTasks =
70+
getBuildTasks(runManager, configuration);
71+
72+
if (!hasBuildTaskForModule(buildTasks, module)) {
73+
BeforeRunTask buildTask = createBuildTask(module);
74+
if (buildTask != null) {
75+
List<BeforeRunTask> tasks = runManager.getBeforeRunTasks(configuration);
76+
tasks.add(buildTask);
77+
runManager.setBeforeRunTasks(configuration, tasks, true);
78+
}
79+
}
80+
}
81+
82+
/**
83+
* Updates the pre-deploy build tasks ({@link BeforeRunTask}) when the deployment source is
84+
* updated.
85+
*
86+
* Similar to {@link BuildDeploymentSourceType#setBuildBeforeRunTask(
87+
* RunConfiguration, ModuleDeploymentSource)}, but it is invoked when switching between
88+
* deployment sources in the UI.
89+
*
90+
* Only creates a new task if one is not already configured. In following the IntelliJ pattern
91+
* used for bundled deployment sources, this does NOT remove any existing tasks.
92+
*/
93+
@Override
94+
public void updateBuildBeforeRunOption(
95+
@NotNull JComponent runConfigurationEditorComponent,
96+
@NotNull Project project,
97+
@NotNull ModuleDeploymentSource source,
98+
boolean select) {
99+
100+
final DataContext dataContext =
101+
DataManager.getInstance().getDataContext(runConfigurationEditorComponent);
102+
final ConfigurationSettingsEditorWrapper editor =
103+
ConfigurationSettingsEditorWrapper.CONFIGURATION_EDITOR_KEY.getData(dataContext);
104+
105+
Module module = source.getModule();
106+
107+
if (module == null || editor == null) {
108+
return;
109+
}
110+
111+
List<BeforeRunTask> buildTasks = editor.getStepsBeforeLaunch();
112+
113+
if (select && !hasBuildTaskForModule(buildTasks, module)) {
114+
BeforeRunTask buildTask = createBuildTask(module);
115+
if (buildTask != null) {
116+
editor.addBeforeLaunchStep(buildTask);
117+
}
118+
}
119+
}
120+
121+
/**
122+
* @return the collection of already configured {@link BeforeRunTask} subtypes for the given
123+
* build-system.
124+
*/
125+
@NotNull
126+
protected abstract Collection<? extends BeforeRunTask> getBuildTasks(
127+
RunManagerEx runManager,
128+
RunConfiguration configuration);
129+
130+
/**
131+
* Creates a new instance of a {@link BeforeRunTask} for the corresponding build-system.
132+
*
133+
* This build task should encapsulate packaging of the build artifact for
134+
* the supplied module.
135+
*
136+
* @param module for which this task is scoped
137+
* @return a new build task
138+
*/
139+
140+
@Nullable
141+
protected abstract BeforeRunTask createBuildTask(Module module);
142+
143+
/**
144+
* Determines if there is already a configured build task in the supplied collection.
145+
*
146+
* Implementors should consider only those tasks corresponding to their build-systems, those
147+
* that produce the build artifact, and those scoped to the supplied module.
148+
*
149+
* @return boolean indicating if a build task exists.
150+
*/
151+
protected abstract boolean hasBuildTaskForModule(
152+
Collection<? extends BeforeRunTask> beforeRunTasks, Module module);
153+
154+
/**
155+
* Manually set the deployment configuration so that its available immediately in the
156+
* deployment configuration dialog even if the user does not trigger any UI actions. This
157+
* prevents downstream npe's in {@link DeployToServerRunConfiguration#checkConfiguration()}.
158+
*/
159+
@SuppressWarnings("unchecked")
160+
private void setConfiguration(@NotNull RunConfiguration configuration) {
161+
if (configuration instanceof DeployToServerRunConfiguration) {
162+
DeployToServerRunConfiguration deployRunConfiguration =
163+
((DeployToServerRunConfiguration) configuration);
164+
deployRunConfiguration.setDeploymentConfiguration(new AppEngineDeploymentConfiguration());
165+
}
166+
}
167+
168+
}

0 commit comments

Comments
 (0)