From 14944c6171147d3895577f73951a9c03d02167dc Mon Sep 17 00:00:00 2001 From: Brian de Alwis Date: Wed, 31 Jan 2018 14:43:51 -0500 Subject: [PATCH] Automatically determine the CLOUD_SDK_MANAGEMENT if not previously set (#2761) --- .../sdk/internal/CloudSdkPreferencesTest.java | 66 +++++++++++++++++-- .../META-INF/MANIFEST.MF | 6 +- .../tools/eclipse/sdk/CloudSdkManager.java | 8 --- .../internal/CloudSdkPreferenceResolver.java | 24 ++++++- .../sdk/internal/CloudSdkPreferences.java | 44 ++++++++++++- .../META-INF/MANIFEST.MF | 5 +- .../test/util/TestPreferencesRule.java | 59 +++++++++++++++++ 7 files changed, 192 insertions(+), 20 deletions(-) create mode 100644 plugins/com.google.cloud.tools.eclipse.test.util/src/com/google/cloud/tools/eclipse/test/util/TestPreferencesRule.java diff --git a/plugins/com.google.cloud.tools.eclipse.sdk.test/src/com/google/cloud/tools/eclipse/sdk/internal/CloudSdkPreferencesTest.java b/plugins/com.google.cloud.tools.eclipse.sdk.test/src/com/google/cloud/tools/eclipse/sdk/internal/CloudSdkPreferencesTest.java index 84ca955e7f..f0fd50ca70 100644 --- a/plugins/com.google.cloud.tools.eclipse.sdk.test/src/com/google/cloud/tools/eclipse/sdk/internal/CloudSdkPreferencesTest.java +++ b/plugins/com.google.cloud.tools.eclipse.sdk.test/src/com/google/cloud/tools/eclipse/sdk/internal/CloudSdkPreferencesTest.java @@ -17,20 +17,76 @@ package com.google.cloud.tools.eclipse.sdk.internal; import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import com.google.cloud.tools.eclipse.sdk.CloudSdkManager; +import com.google.cloud.tools.eclipse.test.util.TestPreferencesRule; import org.eclipse.jface.preference.IPreferenceStore; +import org.junit.After; +import org.junit.Before; +import org.junit.Rule; import org.junit.Test; public class CloudSdkPreferencesTest { + @Rule public TestPreferencesRule preferencesCreator = new TestPreferencesRule(); + private boolean forceManagedSdkFeature; + + @Before + public void setUp() { + forceManagedSdkFeature = CloudSdkManager.forceManagedSdkFeature; + CloudSdkManager.forceManagedSdkFeature = true; + } + + @After + public void tearDown() { + CloudSdkManager.forceManagedSdkFeature = forceManagedSdkFeature; + } @Test public void testInitializeDefaults() { - IPreferenceStore preferences = CloudSdkPreferences.getPreferenceStore(); - preferences.putValue(CloudSdkPreferences.CLOUD_SDK_MANAGEMENT, "MANUAL"); + IPreferenceStore preferences = preferencesCreator.getPreferenceStore(); + new CloudSdkPreferences().initializeDefaultPreferences(preferences); + + assertEquals( + "AUTOMATIC", preferences.getDefaultString(CloudSdkPreferences.CLOUD_SDK_MANAGEMENT)); + } + + @Test + public void testInitializeDefaults_noChangeIfSet() { + IPreferenceStore preferences = preferencesCreator.getPreferenceStore(); + preferences.setValue(CloudSdkPreferences.CLOUD_SDK_MANAGEMENT, "FOO"); + new CloudSdkPreferences().initializeDefaultPreferences(preferences); + + assertEquals("FOO", preferences.getString(CloudSdkPreferences.CLOUD_SDK_MANAGEMENT)); + assertEquals( + "AUTOMATIC", preferences.getDefaultString(CloudSdkPreferences.CLOUD_SDK_MANAGEMENT)); + } - new CloudSdkPreferences().initializeDefaultPreferences(); + @Test + public void testConfigure_noCloudSdkAvailable() { + IPreferenceStore preferences = preferencesCreator.getPreferenceStore(); + + CloudSdkPreferences.configureManagementPreferences(preferences, false /*cloudSdkAvailable*/); + assertFalse(preferences.isDefault(CloudSdkPreferences.CLOUD_SDK_MANAGEMENT)); + assertEquals("AUTOMATIC", preferences.getString(CloudSdkPreferences.CLOUD_SDK_MANAGEMENT)); + } + + @Test + public void testConfigure_cloudSdkAvailable() { + IPreferenceStore preferences = preferencesCreator.getPreferenceStore(); + + CloudSdkPreferences.configureManagementPreferences(preferences, true /*cloudSdkAvailable*/); + assertFalse(preferences.isDefault(CloudSdkPreferences.CLOUD_SDK_MANAGEMENT)); + assertEquals("MANUAL", preferences.getString(CloudSdkPreferences.CLOUD_SDK_MANAGEMENT)); + } + + @Test + public void testConfigure_hasCloudSdkPath() { + IPreferenceStore preferences = preferencesCreator.getPreferenceStore(); + preferences.putValue(CloudSdkPreferences.CLOUD_SDK_PATH, "/a/path"); - assertEquals("AUTOMATIC", - preferences.getDefaultString(CloudSdkPreferences.CLOUD_SDK_MANAGEMENT)); + CloudSdkPreferences.configureManagementPreferences(preferences, false /*cloudSdkAvailable*/); + assertFalse(preferences.isDefault(CloudSdkPreferences.CLOUD_SDK_MANAGEMENT)); + assertEquals("MANUAL", preferences.getString(CloudSdkPreferences.CLOUD_SDK_MANAGEMENT)); } } diff --git a/plugins/com.google.cloud.tools.eclipse.sdk/META-INF/MANIFEST.MF b/plugins/com.google.cloud.tools.eclipse.sdk/META-INF/MANIFEST.MF index 82fbe28dd9..9d1967479e 100644 --- a/plugins/com.google.cloud.tools.eclipse.sdk/META-INF/MANIFEST.MF +++ b/plugins/com.google.cloud.tools.eclipse.sdk/META-INF/MANIFEST.MF @@ -6,10 +6,10 @@ Bundle-Version: 0.1.0.qualifier Bundle-Vendor: Google Inc. Bundle-RequiredExecutionEnvironment: JavaSE-1.7 Bundle-ActivationPolicy: lazy -Require-Bundle: com.google.cloud.tools.appengine;bundle-version="0.4.2", - org.eclipse.equinox.preferences;bundle-version="3.5.300" +Require-Bundle: com.google.cloud.tools.appengine;bundle-version="0.4.2" Import-Package: com.google.common.annotations;version="[20.0.0,21.0.0)", - com.google.common.collect;version="[20.0.0,21.0.0)", + com.google.common.base;version="[20.0.0,21.0.0)", + org.eclipse.core.runtime.preferences, org.eclipse.jface.preference, org.eclipse.osgi.service.debug, org.eclipse.ui.console, diff --git a/plugins/com.google.cloud.tools.eclipse.sdk/src/com/google/cloud/tools/eclipse/sdk/CloudSdkManager.java b/plugins/com.google.cloud.tools.eclipse.sdk/src/com/google/cloud/tools/eclipse/sdk/CloudSdkManager.java index 705e97d720..25ecd93f5e 100644 --- a/plugins/com.google.cloud.tools.eclipse.sdk/src/com/google/cloud/tools/eclipse/sdk/CloudSdkManager.java +++ b/plugins/com.google.cloud.tools.eclipse.sdk/src/com/google/cloud/tools/eclipse/sdk/CloudSdkManager.java @@ -42,12 +42,4 @@ public static boolean isManagedSdkFeatureEnabled() { } return false; } - - /** - * Performs a one-time setup of preferences for the Managed Cloud SDK feature if it has never been - * set up. - */ - public static void setUpInitialPreferences() { - // TODO(chanseok): to be implemented. - } } diff --git a/plugins/com.google.cloud.tools.eclipse.sdk/src/com/google/cloud/tools/eclipse/sdk/internal/CloudSdkPreferenceResolver.java b/plugins/com.google.cloud.tools.eclipse.sdk/src/com/google/cloud/tools/eclipse/sdk/internal/CloudSdkPreferenceResolver.java index 05aa6f48c4..657e4c063e 100644 --- a/plugins/com.google.cloud.tools.eclipse.sdk/src/com/google/cloud/tools/eclipse/sdk/internal/CloudSdkPreferenceResolver.java +++ b/plugins/com.google.cloud.tools.eclipse.sdk/src/com/google/cloud/tools/eclipse/sdk/internal/CloudSdkPreferenceResolver.java @@ -17,15 +17,23 @@ package com.google.cloud.tools.eclipse.sdk.internal; import com.google.cloud.tools.appengine.cloudsdk.CloudSdkResolver; +import com.google.cloud.tools.eclipse.sdk.internal.CloudSdkPreferences.CloudSdkManagementOption; +import com.google.cloud.tools.managedcloudsdk.ManagedCloudSdk; +import com.google.cloud.tools.managedcloudsdk.UnsupportedOsException; import com.google.common.annotations.VisibleForTesting; +import com.google.common.base.Strings; import java.nio.file.Path; import java.nio.file.Paths; +import java.util.logging.Level; +import java.util.logging.Logger; import org.eclipse.jface.preference.IPreferenceStore; /** * Google Cloud SDK locator that uses the user-configured location preference. */ public class CloudSdkPreferenceResolver implements CloudSdkResolver { + private static final Logger logger = Logger.getLogger(CloudSdkPreferenceResolver.class.getName()); + private final IPreferenceStore preferences; public CloudSdkPreferenceResolver() { @@ -39,8 +47,22 @@ public CloudSdkPreferenceResolver() { @Override public Path getCloudSdkPath() { + // We only consult the Managed Cloud SDK when it has been explicitly configured, which + // is done in CloudSdkPreferences. + if (preferences.contains(CloudSdkPreferences.CLOUD_SDK_MANAGEMENT)) { + String managementOption = preferences.getString(CloudSdkPreferences.CLOUD_SDK_MANAGEMENT); + if (CloudSdkManagementOption.AUTOMATIC.name().equals(managementOption)) { + // TODO: Should check and wait on the installation job, if in progress + try { + return ManagedCloudSdk.newManagedSdk().getSdkHome(); + } catch (UnsupportedOsException ex) { + logger.log(Level.SEVERE, "Google Cloud SDK not available", ex); // $NON-NLS-1$ + return null; + } + } + } String value = preferences.getString(CloudSdkPreferences.CLOUD_SDK_PATH); - if (value != null && !value.isEmpty()) { + if (!Strings.isNullOrEmpty(value)) { return Paths.get(value); } return null; diff --git a/plugins/com.google.cloud.tools.eclipse.sdk/src/com/google/cloud/tools/eclipse/sdk/internal/CloudSdkPreferences.java b/plugins/com.google.cloud.tools.eclipse.sdk/src/com/google/cloud/tools/eclipse/sdk/internal/CloudSdkPreferences.java index 223af2cb9a..beea994230 100644 --- a/plugins/com.google.cloud.tools.eclipse.sdk/src/com/google/cloud/tools/eclipse/sdk/internal/CloudSdkPreferences.java +++ b/plugins/com.google.cloud.tools.eclipse.sdk/src/com/google/cloud/tools/eclipse/sdk/internal/CloudSdkPreferences.java @@ -16,6 +16,11 @@ package com.google.cloud.tools.eclipse.sdk.internal; +import com.google.cloud.tools.appengine.cloudsdk.CloudSdk; +import com.google.cloud.tools.appengine.cloudsdk.CloudSdkNotFoundException; +import com.google.cloud.tools.eclipse.sdk.CloudSdkManager; +import com.google.common.annotations.VisibleForTesting; +import com.google.common.base.Strings; import org.eclipse.core.runtime.preferences.AbstractPreferenceInitializer; import org.eclipse.core.runtime.preferences.IEclipsePreferences; import org.eclipse.core.runtime.preferences.InstanceScope; @@ -57,7 +62,42 @@ static IEclipsePreferences getPreferenceNode() { @Override public void initializeDefaultPreferences() { - getPreferenceStore().setDefault(CLOUD_SDK_MANAGEMENT, - CloudSdkManagementOption.AUTOMATIC.name()); + initializeDefaultPreferences(getPreferenceStore()); + } + + @VisibleForTesting + void initializeDefaultPreferences(IPreferenceStore preferences) { + if (CloudSdkManager.isManagedSdkFeatureEnabled()) { + if (!preferences.contains(CLOUD_SDK_MANAGEMENT)) { + // If the CLOUD_SDK_MANAGEMENT preference has not been set, then determine the + // appropriate setting. Note that CloudSdkPreferenceResolver only checks for + // the Managed Cloud SDK when CLOUD_SDK_MANAGEMENT has been explicitly set + // (i.e., this code has been run). + configureManagementPreferences(preferences, isCloudSdkAvailable()); + } + preferences.setDefault(CLOUD_SDK_MANAGEMENT, CloudSdkManagementOption.AUTOMATIC.name()); + } + } + + /** Configure the managed SDK settings given current settings. */ + @VisibleForTesting + static void configureManagementPreferences( + IPreferenceStore preferences, boolean cloudSdkAvailable) { + // has the user previously set the Cloud SDK path? has it been found in a well-known location? + if (!Strings.isNullOrEmpty(preferences.getString(CLOUD_SDK_PATH)) || cloudSdkAvailable) { + preferences.setValue(CLOUD_SDK_MANAGEMENT, CloudSdkManagementOption.MANUAL.name()); + } else { + preferences.setValue(CLOUD_SDK_MANAGEMENT, CloudSdkManagementOption.AUTOMATIC.name()); + } + } + + /** Return {@code true} if the Cloud SDK is available. */ + private static boolean isCloudSdkAvailable() { + try { + new CloudSdk.Builder().build(); + return true; + } catch (CloudSdkNotFoundException ex) { + return false; + } } } diff --git a/plugins/com.google.cloud.tools.eclipse.test.util/META-INF/MANIFEST.MF b/plugins/com.google.cloud.tools.eclipse.test.util/META-INF/MANIFEST.MF index 6e2242de62..651c60d951 100644 --- a/plugins/com.google.cloud.tools.eclipse.test.util/META-INF/MANIFEST.MF +++ b/plugins/com.google.cloud.tools.eclipse.test.util/META-INF/MANIFEST.MF @@ -10,7 +10,8 @@ Bundle-ActivationPolicy: lazy Require-Bundle: com.google.cloud.tools.eclipse.test.dependencies, org.eclipse.ui.ide, org.eclipse.core.jobs, - org.eclipse.wst.validation + org.eclipse.wst.validation, + org.eclipse.equinox.preferences;bundle-version="3.5.300" Import-Package: com.google.cloud.tools.eclipse.appengine.facets, com.google.cloud.tools.eclipse.util, com.google.cloud.tools.eclipse.util.status, @@ -31,11 +32,13 @@ Import-Package: com.google.cloud.tools.eclipse.appengine.facets, org.eclipse.jetty.server;version="9.2.13", org.eclipse.jetty.server.handler;version="9.2.13", org.eclipse.jetty.util.component;version="9.2.13", + org.eclipse.jface.preference, org.eclipse.jface.viewers, org.eclipse.jst.common.project.facet.core, org.eclipse.jst.j2ee.web.project.facet, org.eclipse.swt.widgets, org.eclipse.ui.internal.registry, + org.eclipse.ui.preferences, org.eclipse.wst.common.componentcore.internal.builder, org.eclipse.wst.common.project.facet.core, org.eclipse.wst.common.project.facet.core.internal, diff --git a/plugins/com.google.cloud.tools.eclipse.test.util/src/com/google/cloud/tools/eclipse/test/util/TestPreferencesRule.java b/plugins/com.google.cloud.tools.eclipse.test.util/src/com/google/cloud/tools/eclipse/test/util/TestPreferencesRule.java new file mode 100644 index 0000000000..82baaa242c --- /dev/null +++ b/plugins/com.google.cloud.tools.eclipse.test.util/src/com/google/cloud/tools/eclipse/test/util/TestPreferencesRule.java @@ -0,0 +1,59 @@ +/* + * Copyright 2018 Google Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.google.cloud.tools.eclipse.test.util; + +import java.util.logging.Level; +import java.util.logging.Logger; +import org.eclipse.core.runtime.preferences.IEclipsePreferences; +import org.eclipse.core.runtime.preferences.InstanceScope; +import org.eclipse.jface.preference.IPreferenceStore; +import org.eclipse.ui.preferences.ScopedPreferenceStore; +import org.junit.rules.ExternalResource; +import org.osgi.service.prefs.BackingStoreException; + +/** Test utility to create an empty {@link IEclipsePreferences} or {@link IPreferenceStore}. */ +public class TestPreferencesRule extends ExternalResource { + private static final Logger logger = Logger.getLogger(TestPreferencesRule.class.getName()); + + private String storeId; + private IEclipsePreferences preferences; + + @Override + protected void before() throws Throwable { + storeId = "prefs" + Double.toString(Math.random()).replace(".", ""); + preferences = InstanceScope.INSTANCE.getNode(storeId); + super.before(); + } + + public IEclipsePreferences getNode() { + return preferences; + } + + public IPreferenceStore getPreferenceStore() { + return new ScopedPreferenceStore(InstanceScope.INSTANCE, storeId); + } + + @Override + protected void after() { + try { + preferences.removeNode(); + } catch (BackingStoreException ex) { + logger.log(Level.FINE, "Failed clearing preferences: " + storeId, ex); + } + super.after(); + } +}